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
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
)
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 ok(hwnd
!= NULL
, "class: %s, error: %d\n", lpClassName
, (int) GetLastError());
60 static HWND
new_richedit(HWND parent
)
62 return new_window(RICHEDIT_CLASS20A
, ES_MULTILINE
, parent
);
65 static BOOL
touch_file(LPCWSTR filename
)
69 file
= CreateFileW(filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
70 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
72 if(file
== INVALID_HANDLE_VALUE
)
78 static BOOL
is_existing_file(LPCWSTR filename
)
82 file
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
,
83 OPEN_EXISTING
, 0, NULL
);
84 if(file
== INVALID_HANDLE_VALUE
)
90 static void create_interfaces(HWND
*w
, IRichEditOle
**reOle
, ITextDocument
**txtDoc
,
91 ITextSelection
**txtSel
)
93 *w
= new_richedit(NULL
);
94 SendMessageA(*w
, EM_GETOLEINTERFACE
, 0, (LPARAM
)reOle
);
95 IRichEditOle_QueryInterface(*reOle
, &IID_ITextDocument
,
97 ITextDocument_GetSelection(*txtDoc
, txtSel
);
100 static void release_interfaces(HWND
*w
, IRichEditOle
**reOle
, ITextDocument
**txtDoc
,
101 ITextSelection
**txtSel
)
104 ITextSelection_Release(*txtSel
);
105 ITextDocument_Release(*txtDoc
);
106 IRichEditOle_Release(*reOle
);
110 static ULONG
get_refcount(IUnknown
*iface
)
112 IUnknown_AddRef(iface
);
113 return IUnknown_Release(iface
);
116 #define CHECK_TYPEINFO(disp,expected_riid) _check_typeinfo((IDispatch *)disp, expected_riid, __LINE__)
117 static void _check_typeinfo(IDispatch
* disp
, REFIID expected_riid
, int line
)
125 hr
= IDispatch_GetTypeInfoCount(disp
, &count
);
126 ok_(__FILE__
,line
)(hr
== S_OK
, "IDispatch_GetTypeInfoCount failed: 0x%08x.\n", hr
);
127 ok_(__FILE__
,line
)(count
== 1, "got wrong count: %u.\n", count
);
129 hr
= IDispatch_GetTypeInfo(disp
, 0, LOCALE_SYSTEM_DEFAULT
, &typeinfo
);
130 ok_(__FILE__
,line
)(hr
== S_OK
, "IDispatch_GetTypeInfo failed: 0x%08x.\n", hr
);
132 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
);
133 ok_(__FILE__
,line
)(hr
== S_OK
, "ITypeInfo_GetTypeAttr failed: 0x%08x.\n", hr
);
134 ok_(__FILE__
,line
)(IsEqualGUID(&typeattr
->guid
, expected_riid
),
135 "Unexpected type guid: %s.\n", wine_dbgstr_guid(&typeattr
->guid
));
137 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
138 ITypeInfo_Release(typeinfo
);
141 static void test_Interfaces(void)
143 IRichEditOle
*reOle
= NULL
, *reOle1
= NULL
;
144 ITextDocument
*txtDoc
= NULL
;
145 ITextDocument2Old
*txtDoc2Old
= NULL
;
146 ITextSelection
*txtSel
= NULL
, *txtSel2
;
152 IUnknown
*unk
, *unk2
;
154 w
= new_richedit(NULL
);
156 skip("Couldn't create window\n");
160 res
= SendMessageA(w
, EM_GETOLEINTERFACE
, 0, (LPARAM
)&reOle
);
161 ok(res
, "SendMessage\n");
162 ok(reOle
!= NULL
, "EM_GETOLEINTERFACE\n");
163 EXPECT_REF(reOle
, 2);
165 res
= SendMessageA(w
, EM_GETOLEINTERFACE
, 0, (LPARAM
)&reOle1
);
166 ok(res
== 1, "SendMessage\n");
167 ok(reOle1
== reOle
, "Should not return a new IRichEditOle interface\n");
168 EXPECT_REF(reOle
, 3);
170 hres
= IRichEditOle_QueryInterface(reOle
, &IID_ITextDocument
,
172 ok(hres
== S_OK
, "IRichEditOle_QueryInterface\n");
173 ok(txtDoc
!= NULL
, "IRichEditOle_QueryInterface\n");
174 CHECK_TYPEINFO(txtDoc
, &IID_ITextDocument
);
176 hres
= ITextDocument_GetSelection(txtDoc
, NULL
);
177 ok(hres
== E_INVALIDARG
, "ITextDocument_GetSelection: 0x%x\n", hres
);
179 EXPECT_REF(txtDoc
, 4);
181 hres
= ITextDocument_GetSelection(txtDoc
, &txtSel
);
182 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
184 hres
= ITextDocument_QueryInterface(txtDoc
, &IID_IUnknown
, (void **)&unk
);
185 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
186 hres
= ITextSelection_QueryInterface(txtSel
, &IID_IUnknown
, (void **)&unk2
);
187 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
188 ok(unk
!= unk2
, "unknowns are the same\n");
189 IUnknown_Release(unk2
);
190 IUnknown_Release(unk
);
192 EXPECT_REF(txtDoc
, 4);
193 EXPECT_REF(txtSel
, 2);
195 hres
= ITextDocument_GetSelection(txtDoc
, &txtSel2
);
196 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
197 ok(txtSel2
== txtSel
, "got %p, %p\n", txtSel
, txtSel2
);
199 EXPECT_REF(txtDoc
, 4);
200 EXPECT_REF(txtSel
, 3);
202 ITextSelection_Release(txtSel2
);
205 hres
= ITextSelection_QueryInterface(txtSel
, &IID_ITextSelection
, (void **) &punk
);
206 ok(hres
== S_OK
, "ITextSelection_QueryInterface\n");
207 ok(punk
!= NULL
, "ITextSelection_QueryInterface\n");
208 IUnknown_Release(punk
);
211 hres
= ITextSelection_QueryInterface(txtSel
, &IID_ITextRange
, (void **) &punk
);
212 ok(hres
== S_OK
, "ITextSelection_QueryInterface\n");
213 ok(punk
!= NULL
, "ITextSelection_QueryInterface\n");
214 IUnknown_Release(punk
);
217 hres
= ITextSelection_QueryInterface(txtSel
, &IID_IDispatch
, (void **) &punk
);
218 ok(hres
== S_OK
, "ITextSelection_QueryInterface\n");
219 ok(punk
!= NULL
, "ITextSelection_QueryInterface\n");
220 IUnknown_Release(punk
);
223 hres
= IRichEditOle_QueryInterface(reOle
, &IID_IOleClientSite
, (void **) &punk
);
224 ok(hres
== E_NOINTERFACE
, "IRichEditOle_QueryInterface\n");
227 hres
= IRichEditOle_QueryInterface(reOle
, &IID_IOleWindow
, (void **) &punk
);
228 ok(hres
== E_NOINTERFACE
, "IRichEditOle_QueryInterface\n");
231 hres
= IRichEditOle_QueryInterface(reOle
, &IID_IOleInPlaceSite
, (void **) &punk
);
232 ok(hres
== E_NOINTERFACE
, "IRichEditOle_QueryInterface\n");
234 hres
= IRichEditOle_QueryInterface(reOle
, &IID_ITextDocument2Old
, (void **)&txtDoc2Old
);
235 ok(hres
== S_OK
, "IRichEditOle_QueryInterface\n");
236 ok(txtDoc2Old
!= NULL
, "IRichEditOle_QueryInterface\n");
237 ok((ITextDocument
*)txtDoc2Old
== txtDoc
, "interface pointer isn't equal.\n");
238 EXPECT_REF(txtDoc2Old
, 5);
239 EXPECT_REF(reOle
, 5);
240 CHECK_TYPEINFO(txtDoc2Old
, &IID_ITextDocument
);
242 ITextDocument2Old_Release(txtDoc2Old
);
244 ITextDocument_Release(txtDoc
);
245 IRichEditOle_Release(reOle
);
246 refcount
= IRichEditOle_Release(reOle
);
247 ok(refcount
== 1, "got wrong ref count: %d\n", refcount
);
250 /* Methods should return CO_E_RELEASED if the backing document has
251 been released. One test should suffice. */
252 hres
= ITextSelection_CanEdit(txtSel
, NULL
);
253 ok(hres
== CO_E_RELEASED
, "ITextSelection after ITextDocument destroyed\n");
255 ITextSelection_Release(txtSel
);
257 w
= new_richedit(NULL
);
258 res
= SendMessageA(w
, EM_GETOLEINTERFACE
, 0, (LPARAM
)&reOle
);
259 ok(res
, "SendMessage\n");
260 ok(reOle
!= NULL
, "EM_GETOLEINTERFACE\n");
262 hres
= IRichEditOle_QueryInterface(reOle
, &IID_ITextDocument2Old
, (void **)&txtDoc2Old
);
263 ok(hres
== S_OK
, "IRichEditOle_QueryInterface failed: 0x%08x.\n", hres
);
264 ok(txtDoc2Old
!= NULL
, "IRichEditOle_QueryInterface\n");
265 CHECK_TYPEINFO(txtDoc2Old
, &IID_ITextDocument
);
266 ITextDocument2Old_Release(txtDoc2Old
);
267 IRichEditOle_Release(reOle
);
271 static void test_ITextDocument_Open(void)
273 IRichEditOle
*reOle
= NULL
;
274 ITextDocument
*txtDoc
= NULL
;
275 ITextSelection
*txtSel
= NULL
;
280 WCHAR filename
[] = {'t', 'e', 's', 't','.','t','x','t', 0};
283 static const CHAR chACP
[] = "TestSomeText";
284 static const CHAR chUTF8
[] = "\xef\xbb\xbfTextWithUTF8BOM";
285 static const WCHAR chUTF16
[] = {0xfeff, 'T', 'e', 's', 't', 'S', 'o', 'm',
286 'e', 'T', 'e', 'x', 't', 0};
288 #define MAX_BUF_LEN 1024
289 CHAR bufACP
[MAX_BUF_LEN
];
290 WCHAR bufUnicode
[MAX_BUF_LEN
];
292 static const int tomConstantsSingle
[] =
294 tomReadOnly
, tomShareDenyRead
, tomShareDenyWrite
,
295 tomCreateAlways
, tomOpenExisting
, tomOpenAlways
,
296 tomTruncateExisting
, tomRTF
, tomText
299 static const int tomConstantsMulti
[] =
301 tomReadOnly
|tomShareDenyRead
|tomPasteFile
, tomReadOnly
|tomPasteFile
,
302 tomReadOnly
|tomShareDenyWrite
|tomPasteFile
,
303 tomReadOnly
|tomShareDenyRead
|tomShareDenyWrite
|tomPasteFile
, tomShareDenyWrite
|tomPasteFile
,
304 tomShareDenyRead
|tomShareDenyWrite
|tomPasteFile
, tomShareDenyRead
|tomPasteFile
,
305 tomShareDenyRead
|tomShareDenyWrite
, tomReadOnly
|tomShareDenyRead
|tomShareDenyWrite
,
306 tomReadOnly
|tomShareDenyWrite
, tomReadOnly
|tomShareDenyRead
309 int tomNumSingle
= ARRAY_SIZE(tomConstantsSingle
);
310 int tomNumMulti
= ARRAY_SIZE(tomConstantsMulti
);
313 V_VT(&testfile
) = VT_BSTR
;
314 V_BSTR(&testfile
) = SysAllocString(filename
);
316 for(i
=0; i
< tomNumSingle
; i
++)
318 touch_file(filename
);
319 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
320 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomConstantsSingle
[i
], CP_ACP
);
321 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
322 tomConstantsSingle
[i
], hres
);
323 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
324 DeleteFileW(filename
);
326 touch_file(filename
);
327 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
328 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomConstantsSingle
[i
], CP_UTF8
);
329 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
330 tomConstantsSingle
[i
], hres
);
331 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
332 DeleteFileW(filename
);
335 for(i
=0; i
< tomNumMulti
; i
++)
337 touch_file(filename
);
338 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
339 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomConstantsMulti
[i
], CP_ACP
);
340 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
341 tomConstantsMulti
[i
], hres
);
342 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
343 DeleteFileW(filename
);
345 touch_file(filename
);
346 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
347 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomConstantsMulti
[i
], CP_UTF8
);
348 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
349 tomConstantsMulti
[i
], hres
);
350 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
351 DeleteFileW(filename
);
354 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
355 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomCreateAlways
, CP_ACP
);
356 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open should success Codepage:CP_ACP\n");
357 todo_wine
ok(is_existing_file(filename
), "ITextDocument_Open should create a file\n");
358 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
359 DeleteFileW(filename
);
361 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
362 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomCreateAlways
, CP_UTF8
);
363 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open should success Codepage:CP_UTF8\n");
364 todo_wine
ok(is_existing_file(filename
), "ITextDocument_Open should create a file\n");
365 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
366 DeleteFileW(filename
);
368 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
369 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomOpenAlways
, CP_ACP
);
370 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open should success Codepage:CP_ACP\n");
371 todo_wine
ok(is_existing_file(filename
), "ITextDocument_Open should create a file\n");
372 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
373 DeleteFileW(filename
);
375 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
376 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomOpenAlways
, CP_UTF8
);
377 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open should success Codepage:CP_UTF8\n");
378 todo_wine
ok(is_existing_file(filename
), "ITextDocument_Open should create a file\n");
379 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
380 DeleteFileW(filename
);
382 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
383 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomCreateNew
, CP_ACP
);
384 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open should success Codepage:CP_ACP\n");
385 todo_wine
ok(is_existing_file(filename
), "ITextDocument_Open should create a file\n");
386 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
387 DeleteFileW(filename
);
389 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
390 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomCreateNew
, CP_UTF8
);
391 todo_wine
ok(hres
== S_OK
, "ITextDocument_Open should success Codepage:CP_UTF8\n");
392 todo_wine
ok(is_existing_file(filename
), "ITextDocument_Open should create a file\n");
393 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
394 DeleteFileW(filename
);
396 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
397 touch_file(filename
);
398 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomCreateNew
, CP_ACP
);
399 todo_wine
ok(hres
== HRESULT_FROM_WIN32(ERROR_FILE_EXISTS
), "ITextDocument_Open should fail Codepage:CP_ACP\n");
400 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
401 DeleteFileW(filename
);
403 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
404 touch_file(filename
);
405 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomCreateNew
, CP_UTF8
);
406 todo_wine
ok(hres
== HRESULT_FROM_WIN32(ERROR_FILE_EXISTS
), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
407 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
408 DeleteFileW(filename
);
410 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
411 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomOpenExisting
, CP_ACP
);
412 todo_wine
ok(hres
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "ITextDocument_Open should fail Codepage:CP_ACP\n");
413 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
415 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
416 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomOpenExisting
, CP_UTF8
);
417 todo_wine
ok(hres
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
418 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
420 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
421 DeleteFileW(filename
);
422 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomText
, CP_ACP
);
424 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
425 ok(is_existing_file(filename
) == TRUE
, "a file should be created default\n");
427 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
428 DeleteFileW(filename
);
430 /* test of share mode */
431 touch_file(filename
);
432 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
433 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomShareDenyRead
, CP_ACP
);
435 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
436 SetLastError(0xdeadbeef);
437 hFile
= CreateFileW(filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
438 FILE_ATTRIBUTE_NORMAL
, NULL
);
439 todo_wine
ok(GetLastError() == ERROR_SHARING_VIOLATION
, "ITextDocument_Open should fail\n");
441 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
442 DeleteFileW(filename
);
444 touch_file(filename
);
445 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
446 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomShareDenyWrite
, CP_ACP
);
448 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
449 SetLastError(0xdeadbeef);
450 hFile
= CreateFileW(filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
451 FILE_ATTRIBUTE_NORMAL
, NULL
);
452 todo_wine
ok(GetLastError() == ERROR_SHARING_VIOLATION
, "ITextDocument_Open should fail\n");
454 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
455 DeleteFileW(filename
);
457 touch_file(filename
);
458 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
459 SetLastError(0xdeadbeef);
460 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomShareDenyWrite
|tomShareDenyRead
, CP_ACP
);
462 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
463 hFile
= CreateFileW(filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
464 FILE_ATTRIBUTE_NORMAL
, NULL
);
465 todo_wine
ok(GetLastError() == ERROR_SHARING_VIOLATION
, "ITextDocument_Open should fail\n");
467 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
468 DeleteFileW(filename
);
470 /* tests to check the content */
471 hFile
= CreateFileW(filename
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
472 FILE_ATTRIBUTE_NORMAL
, NULL
);
473 WriteFile(hFile
, chACP
, sizeof(chACP
)-sizeof(CHAR
), &dw
, NULL
);
475 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
476 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomReadOnly
, CP_ACP
);
478 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
479 result
= SendMessageA(w
, WM_GETTEXT
, 1024, (LPARAM
)bufACP
);
480 todo_wine
ok(result
== 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result
);
481 result
= strcmp(bufACP
, chACP
);
482 todo_wine
ok(result
== 0, "ITextDocument_Open: Test ASCII set wrong text: Result: %s\n", bufACP
);
483 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
484 DeleteFileW(filename
);
486 hFile
= CreateFileW(filename
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
487 FILE_ATTRIBUTE_NORMAL
, NULL
);
488 WriteFile(hFile
, chUTF8
, sizeof(chUTF8
)-sizeof(CHAR
), &dw
, NULL
);
490 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
491 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomReadOnly
, CP_UTF8
);
493 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
494 result
= SendMessageA(w
, WM_GETTEXT
, 1024, (LPARAM
)bufACP
);
495 todo_wine
ok(result
== 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result
);
496 result
= strcmp(bufACP
, &chUTF8
[3]);
497 todo_wine
ok(result
== 0, "ITextDocument_Open: Test UTF-8 set wrong text: Result: %s\n", bufACP
);
498 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
499 DeleteFileW(filename
);
501 hFile
= CreateFileW(filename
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
502 FILE_ATTRIBUTE_NORMAL
, NULL
);
503 WriteFile(hFile
, chUTF16
, sizeof(chUTF16
)-sizeof(WCHAR
), &dw
, NULL
);
505 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
506 hres
= ITextDocument_Open(txtDoc
, &testfile
, tomReadOnly
, 1200);
508 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
509 result
= SendMessageW(w
, WM_GETTEXT
, 1024, (LPARAM
)bufUnicode
);
510 todo_wine
ok(result
== 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result
);
511 result
= lstrcmpW(bufUnicode
, &chUTF16
[1]);
512 todo_wine
ok(result
== 0, "ITextDocument_Open: Test UTF-16 set wrong text: Result: %s\n", wine_dbgstr_w(bufUnicode
));
513 release_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
514 DeleteFileW(filename
);
516 VariantClear(&testfile
);
519 static void test_GetText(void)
522 IRichEditOle
*reOle
= NULL
;
523 ITextDocument
*txtDoc
= NULL
;
524 ITextSelection
*txtSel
= NULL
;
528 static const CHAR test_text1
[] = "TestSomeText";
529 static const WCHAR bufW1
[] = {'T', 'e', 's', 't', 0};
530 static const WCHAR bufW2
[] = {'T', 'e', 'x', 't', '\r', 0};
531 static const WCHAR bufW3
[] = {'T', 'e', 'x', 't', 0};
532 static const WCHAR bufW4
[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
533 'e', 'T', 'e', 'x', 't', '\r', 0};
534 static const WCHAR bufW5
[] = {'\r', 0};
535 static const WCHAR bufW6
[] = {'T','e','s','t','S','o','m','e','T',0};
536 BOOL is64bit
= sizeof(void *) > sizeof(int);
539 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
540 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
544 SendMessageA(w
, EM_SETSEL
, first
, lim
);
545 hres
= ITextSelection_GetText(txtSel
, &bstr
);
546 ok(hres
== S_OK
, "ITextSelection_GetText\n");
547 ok(!lstrcmpW(bstr
, bufW1
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
551 SendMessageA(w
, EM_SETSEL
, first
, lim
);
552 hres
= ITextSelection_GetText(txtSel
, &bstr
);
553 ok(hres
== S_OK
, "ITextSelection_GetText\n");
554 ok(!lstrcmpW(bstr
, bufW1
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
558 SendMessageA(w
, EM_SETSEL
, first
, lim
);
559 hres
= ITextSelection_GetText(txtSel
, &bstr
);
560 ok(hres
== S_OK
, "ITextSelection_GetText\n");
561 ok(!bstr
, "got wrong text: %s\n", wine_dbgstr_w(bstr
));
565 hres
= ITextSelection_GetText(txtSel
, NULL
);
566 ok(hres
== E_INVALIDARG
, "ITextSelection_GetText\n");
570 SendMessageA(w
, EM_SETSEL
, first
, lim
);
571 hres
= ITextSelection_GetText(txtSel
, &bstr
);
572 ok(hres
== S_OK
, "ITextSelection_GetText\n");
573 ok(!lstrcmpW(bstr
, bufW3
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
577 SendMessageA(w
, EM_SETSEL
, first
, lim
);
578 hres
= ITextSelection_GetText(txtSel
, &bstr
);
579 ok(hres
== S_OK
, "ITextSelection_GetText\n");
580 ok(!lstrcmpW(bstr
, bufW2
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
583 first
= 12; lim
= 13;
584 SendMessageA(w
, EM_SETSEL
, first
, lim
);
585 hres
= ITextSelection_GetText(txtSel
, &bstr
);
586 ok(hres
== S_OK
, "ITextSelection_GetText\n");
587 ok(!lstrcmpW(bstr
, bufW5
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
591 SendMessageA(w
, EM_SETSEL
, first
, lim
);
592 hres
= ITextSelection_GetText(txtSel
, &bstr
);
593 ok(hres
== S_OK
, "ITextSelection_GetText\n");
594 ok(!lstrcmpW(bstr
, bufW4
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
598 SendMessageA(w
, EM_SETSEL
, first
, lim
);
599 hres
= ITextSelection_GetText(txtSel
, &bstr
);
600 ok(hres
== S_OK
, "ITextSelection_GetText\n");
601 ok(!bstr
, "got wrong text: %s\n", wine_dbgstr_w(bstr
));
604 hres
= ITextDocument_Range(txtDoc
, 0, 4, &range
);
605 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
606 hres
= ITextRange_GetText(range
, &bstr
);
607 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
608 ok(!lstrcmpW(bstr
, bufW1
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
611 ITextRange_Release(range
);
613 hres
= ITextDocument_Range(txtDoc
, 4, 0, &range
);
614 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
615 hres
= ITextRange_GetText(range
, &bstr
);
616 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
617 ok(!lstrcmpW(bstr
, bufW1
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
620 ITextRange_Release(range
);
622 hres
= ITextDocument_Range(txtDoc
, 1, 1, &range
);
623 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
624 hres
= ITextRange_GetText(range
, &bstr
);
625 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
626 ok(!bstr
, "got wrong text: %s\n", wine_dbgstr_w(bstr
));
629 hres
= ITextRange_GetText(range
, NULL
);
630 ok(hres
== E_INVALIDARG
, "got 0x%08x\n", hres
);
632 ITextRange_Release(range
);
634 hres
= ITextDocument_Range(txtDoc
, 8, 12, &range
);
635 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
636 hres
= ITextRange_GetText(range
, &bstr
);
637 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
638 ok(!lstrcmpW(bstr
, bufW3
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
641 ITextRange_Release(range
);
643 hres
= ITextDocument_Range(txtDoc
, 8, 13, &range
);
644 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
645 hres
= ITextRange_GetText(range
, &bstr
);
646 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
647 ok(!lstrcmpW(bstr
, bufW2
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
650 ITextRange_Release(range
);
652 hres
= ITextDocument_Range(txtDoc
, 12, 13, &range
);
653 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
654 hres
= ITextRange_GetText(range
, &bstr
);
655 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
656 ok(!lstrcmpW(bstr
, bufW5
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
659 ITextRange_Release(range
);
661 hres
= ITextDocument_Range(txtDoc
, 0, -1, &range
);
662 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
663 hres
= ITextRange_GetText(range
, &bstr
);
664 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
665 ok(!bstr
, "got wrong text: %s\n", wine_dbgstr_w(bstr
));
666 ITextRange_Release(range
);
668 hres
= ITextDocument_Range(txtDoc
, -1, 9, &range
);
669 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
670 hres
= ITextRange_GetText(range
, &bstr
);
671 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
672 ok(!lstrcmpW(bstr
, bufW6
), "got wrong text: %s\n", wine_dbgstr_w(bstr
));
676 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
678 /* detached selection/range */
680 bstr
= (void*)0xdeadbeef;
681 hres
= ITextSelection_GetText(txtSel
, &bstr
);
682 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
684 ok(bstr
== NULL
, "got %p\n", bstr
);
686 bstr
= (void*)0xdeadbeef;
687 hres
= ITextRange_GetText(range
, &bstr
);
688 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
690 ok(bstr
== NULL
, "got %p\n", bstr
);
693 hres
= ITextSelection_GetText(txtSel
, NULL
);
694 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
696 hres
= ITextRange_GetText(range
, NULL
);
697 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
700 ITextRange_Release(range
);
701 ITextSelection_Release(txtSel
);
704 static void test_ITextDocument_Range(void)
706 static const CHAR test_text1
[] = "TestSomeText";
708 IRichEditOle
*reOle
= NULL
;
709 ITextDocument
*txtDoc
= NULL
;
710 ITextRange
*txtRge
, *range2
;
714 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
715 hres
= ITextDocument_Range(txtDoc
, 0, 0, &txtRge
);
716 ok(hres
== S_OK
, "ITextDocument_Range fails 0x%x.\n", hres
);
717 EXPECT_REF(txtRge
, 1);
719 hres
= ITextDocument_Range(txtDoc
, 0, 0, &range2
);
720 ok(hres
== S_OK
, "ITextDocument_Range fails 0x%x.\n", hres
);
721 ok(range2
!= txtRge
, "A new pointer should be returned\n");
722 ITextRange_Release(range2
);
724 hres
= ITextDocument_Range(txtDoc
, 0, 0, NULL
);
725 ok(hres
== E_INVALIDARG
, "ITextDocument_Range should fail 0x%x.\n", hres
);
727 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
729 hres
= ITextDocument_Range(txtDoc
, 8, 30, &range2
);
730 ok(hres
== S_OK
, "ITextDocument_Range fails 0x%x.\n", hres
);
731 hres
= ITextRange_GetStart(range2
, &value
);
732 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
733 ok(value
== 8, "got %d\n", value
);
735 hres
= ITextRange_GetEnd(range2
, &value
);
736 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
737 ok(value
== 13, "got %d\n", value
);
738 ITextRange_Release(range2
);
740 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
741 hres
= ITextRange_CanEdit(txtRge
, NULL
);
742 ok(hres
== CO_E_RELEASED
, "ITextRange after ITextDocument destroyed\n");
743 ITextRange_Release(txtRge
);
746 static void test_ITextRange_GetChar(void)
749 IRichEditOle
*reOle
= NULL
;
750 ITextDocument
*txtDoc
= NULL
;
751 ITextRange
*txtRge
= NULL
;
755 static const CHAR test_text1
[] = "TestSomeText";
758 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
759 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
760 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
761 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
763 hres
= ITextRange_GetChar(txtRge
, &pch
);
764 ok(hres
== S_OK
, "ITextRange_GetChar\n");
765 ok(pch
== 'T', "got wrong char: %c\n", pch
);
766 ITextRange_Release(txtRge
);
767 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
770 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
771 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
772 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
773 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
775 hres
= ITextRange_GetChar(txtRge
, &pch
);
776 ok(hres
== S_OK
, "ITextRange_GetChar\n");
777 ok(pch
== 'T', "got wrong char: %c\n", pch
);
778 ITextRange_Release(txtRge
);
779 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
781 first
= 12; lim
= 12;
782 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
783 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
784 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
785 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
787 hres
= ITextRange_GetChar(txtRge
, &pch
);
788 ok(hres
== S_OK
, "ITextRange_GetChar\n");
789 ok(pch
== '\r', "got wrong char: %c\n", pch
);
790 ITextRange_Release(txtRge
);
791 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
793 first
= 13; lim
= 13;
794 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
795 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
796 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
797 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
799 hres
= ITextRange_GetChar(txtRge
, &pch
);
800 ok(hres
== S_OK
, "ITextRange_GetChar\n");
801 ok(pch
== '\r', "got wrong char: %c\n", pch
);
802 ITextRange_Release(txtRge
);
803 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
805 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
806 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
807 first
= 12; lim
= 12;
808 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
809 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
810 hres
= ITextRange_GetChar(txtRge
, NULL
);
811 ok(hres
== E_INVALIDARG
, "ITextRange_GetChar\n");
813 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
815 hres
= ITextRange_GetChar(txtRge
, NULL
);
816 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
818 hres
= ITextRange_GetChar(txtRge
, &pch
);
819 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
821 ITextRange_Release(txtRge
);
824 /* Helper function for testing ITextRange_ScrollIntoView */
825 static void check_range(HWND w
, ITextDocument
* doc
, int first
, int lim
,
826 LONG bStart
, int expected_nonzero
)
829 ITextRange
*txtRge
= NULL
;
832 si
.cbSize
= sizeof(SCROLLINFO
);
833 si
.fMask
= SIF_POS
| SIF_RANGE
;
835 hres
= ITextDocument_Range(doc
, first
, lim
, &txtRge
);
836 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
837 hres
= ITextRange_ScrollIntoView(txtRge
, bStart
);
838 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
839 GetScrollInfo(w
, SB_VERT
, &si
);
840 if (expected_nonzero
) {
842 "Scrollbar at 0, should be >0. (TextRange %d-%d, scroll range %d-%d.)\n",
843 first
, lim
, si
.nMin
, si
.nMax
);
846 "Scrollbar at %d, should be 0. (TextRange %d-%d, scroll range %d-%d.)\n",
847 si
.nPos
, first
, lim
, si
.nMin
, si
.nMax
);
851 static void test_ITextRange_ScrollIntoView(void)
854 IRichEditOle
*reOle
= NULL
;
855 ITextDocument
*txtDoc
= NULL
;
856 ITextRange
*txtRge
= NULL
;
858 static const CHAR test_text1
[] = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10";
860 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
861 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
863 /* Scroll to the top. */
864 check_range(w
, txtDoc
, 0, 1, tomStart
, 0);
865 check_range(w
, txtDoc
, 0, 1, tomEnd
, 0);
867 /* Scroll to the bottom. */
868 check_range(w
, txtDoc
, 19, 20, tomStart
, 1);
869 check_range(w
, txtDoc
, 19, 20, tomEnd
, 1);
871 /* Back up to the top. */
872 check_range(w
, txtDoc
, 0, 1, tomStart
, 0);
873 check_range(w
, txtDoc
, 0, 1, tomEnd
, 0);
876 check_range(w
, txtDoc
, 0, 20, tomStart
, 0);
877 check_range(w
, txtDoc
, 0, 20, tomEnd
, 1);
879 hres
= ITextDocument_Range(txtDoc
, 0, 0, &txtRge
);
880 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
881 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
882 hres
= ITextRange_ScrollIntoView(txtRge
, tomStart
);
883 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
884 ITextRange_Release(txtRge
);
887 static void test_ITextSelection_GetChar(void)
890 IRichEditOle
*reOle
= NULL
;
891 ITextDocument
*txtDoc
= NULL
;
892 ITextSelection
*txtSel
= NULL
;
896 static const CHAR test_text1
[] = "TestSomeText";
898 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
899 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
902 SendMessageA(w
, EM_SETSEL
, first
, lim
);
904 hres
= ITextSelection_GetChar(txtSel
, &pch
);
905 ok(hres
== S_OK
, "ITextSelection_GetChar\n");
906 ok(pch
== 'T', "got wrong char: %c\n", pch
);
909 SendMessageA(w
, EM_SETSEL
, first
, lim
);
911 hres
= ITextSelection_GetChar(txtSel
, &pch
);
912 ok(hres
== S_OK
, "ITextSelection_GetChar\n");
913 ok(pch
== 'T', "got wrong char: %c\n", pch
);
915 first
= 12; lim
= 12;
916 SendMessageA(w
, EM_SETSEL
, first
, lim
);
918 hres
= ITextSelection_GetChar(txtSel
, &pch
);
919 ok(hres
== S_OK
, "ITextSelection_GetChar\n");
920 ok(pch
== '\r', "got wrong char: %c\n", pch
);
922 first
= 13; lim
= 13;
923 SendMessageA(w
, EM_SETSEL
, first
, lim
);
925 hres
= ITextSelection_GetChar(txtSel
, &pch
);
926 ok(hres
== S_OK
, "ITextSelection_GetChar\n");
927 ok(pch
== '\r', "got wrong char: %c\n", pch
);
929 hres
= ITextSelection_GetChar(txtSel
, NULL
);
930 ok(hres
== E_INVALIDARG
, "ITextSelection_GetChar\n");
932 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
934 hres
= ITextSelection_GetChar(txtSel
, NULL
);
935 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
937 hres
= ITextSelection_GetChar(txtSel
, &pch
);
938 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
940 ITextSelection_Release(txtSel
);
943 static void test_ITextRange_GetStart_GetEnd(void)
946 IRichEditOle
*reOle
= NULL
;
947 ITextDocument
*txtDoc
= NULL
;
948 ITextRange
*txtRge
= NULL
;
952 static const CHAR test_text1
[] = "TestSomeText";
954 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
955 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
958 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
959 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
961 hres
= ITextRange_GetStart(txtRge
, &start
);
962 ok(hres
== S_OK
, "ITextRange_GetStart\n");
963 ok(start
== 1, "got wrong start value: %d\n", start
);
965 hres
= ITextRange_GetEnd(txtRge
, &end
);
966 ok(hres
== S_OK
, "ITextRange_GetEnd\n");
967 ok(end
== 6, "got wrong end value: %d\n", end
);
968 ITextRange_Release(txtRge
);
971 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
972 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
974 hres
= ITextRange_GetStart(txtRge
, &start
);
975 ok(hres
== S_OK
, "ITextRange_GetStart\n");
976 ok(start
== 1, "got wrong start value: %d\n", start
);
978 hres
= ITextRange_GetEnd(txtRge
, &end
);
979 ok(hres
== S_OK
, "ITextRange_GetEnd\n");
980 ok(end
== 6, "got wrong end value: %d\n", end
);
981 ITextRange_Release(txtRge
);
983 first
= -1; lim
= 13;
984 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
985 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
987 hres
= ITextRange_GetStart(txtRge
, &start
);
988 ok(hres
== S_OK
, "ITextRange_GetStart\n");
989 ok(start
== 0, "got wrong start value: %d\n", start
);
991 hres
= ITextRange_GetEnd(txtRge
, &end
);
992 ok(hres
== S_OK
, "ITextRange_GetEnd\n");
993 ok(end
== 13, "got wrong end value: %d\n", end
);
994 ITextRange_Release(txtRge
);
996 first
= 13; lim
= 13;
997 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
998 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1000 hres
= ITextRange_GetStart(txtRge
, &start
);
1001 ok(hres
== S_OK
, "ITextRange_GetStart\n");
1002 ok(start
== 12, "got wrong start value: %d\n", start
);
1004 hres
= ITextRange_GetEnd(txtRge
, &end
);
1005 ok(hres
== S_OK
, "ITextRange_GetEnd\n");
1006 ok(end
== 12, "got wrong end value: %d\n", end
);
1009 hres
= ITextRange_SetStart(txtRge
, 0);
1010 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1013 hres
= ITextRange_SetStart(txtRge
, 0);
1014 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1016 hres
= ITextRange_SetStart(txtRge
, 1);
1017 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1019 /* negative resets to 0, return value is S_FALSE when
1020 position wasn't changed */
1021 hres
= ITextRange_SetStart(txtRge
, -1);
1022 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1024 hres
= ITextRange_SetStart(txtRge
, -1);
1025 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1027 hres
= ITextRange_SetStart(txtRge
, 0);
1028 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1031 hres
= ITextRange_GetStart(txtRge
, &start
);
1032 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1033 ok(start
== 0, "got %d\n", start
);
1035 /* greater than initial end, but less than total char count */
1036 hres
= ITextRange_SetStart(txtRge
, 1);
1037 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1039 hres
= ITextRange_SetEnd(txtRge
, 3);
1040 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1042 hres
= ITextRange_SetStart(txtRge
, 10);
1043 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1046 hres
= ITextRange_GetStart(txtRge
, &start
);
1047 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1048 ok(start
== 10, "got %d\n", start
);
1051 hres
= ITextRange_GetEnd(txtRge
, &end
);
1052 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1053 ok(end
== 10, "got %d\n", end
);
1055 /* more that total text length */
1056 hres
= ITextRange_SetStart(txtRge
, 50);
1057 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1060 hres
= ITextRange_GetStart(txtRge
, &start
);
1061 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1062 ok(start
== 12, "got %d\n", start
);
1065 hres
= ITextRange_GetEnd(txtRge
, &end
);
1066 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1067 ok(end
== 12, "got %d\n", end
);
1070 hres
= ITextRange_SetStart(txtRge
, 0);
1071 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1074 hres
= ITextRange_SetEnd(txtRge
, 5);
1075 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1077 hres
= ITextRange_SetEnd(txtRge
, 5);
1078 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1080 /* negative resets to 0 */
1081 hres
= ITextRange_SetEnd(txtRge
, -1);
1082 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1085 hres
= ITextRange_GetEnd(txtRge
, &end
);
1086 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1087 ok(end
== 0, "got %d\n", end
);
1090 hres
= ITextRange_GetStart(txtRge
, &start
);
1091 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1092 ok(start
== 0, "got %d\n", start
);
1094 /* greater than initial end, but less than total char count */
1095 hres
= ITextRange_SetStart(txtRge
, 3);
1096 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1098 hres
= ITextRange_SetEnd(txtRge
, 1);
1099 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1102 hres
= ITextRange_GetStart(txtRge
, &start
);
1103 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1104 ok(start
== 1, "got %d\n", start
);
1107 hres
= ITextRange_GetEnd(txtRge
, &end
);
1108 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1109 ok(end
== 1, "got %d\n", end
);
1111 /* more than total count */
1112 hres
= ITextRange_SetEnd(txtRge
, 50);
1113 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1116 hres
= ITextRange_GetStart(txtRge
, &start
);
1117 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1118 ok(start
== 1, "got %d\n", start
);
1121 hres
= ITextRange_GetEnd(txtRge
, &end
);
1122 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1123 ok(end
== 13, "got %d\n", end
);
1126 hres
= ITextRange_SetEnd(txtRge
, 0);
1127 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1130 hres
= ITextRange_GetStart(txtRge
, &start
);
1131 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1132 ok(start
== 0, "got %d\n", start
);
1135 hres
= ITextRange_GetEnd(txtRge
, &end
);
1136 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1137 ok(end
== 0, "got %d\n", end
);
1139 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1141 /* detached range */
1142 hres
= ITextRange_SetStart(txtRge
, 0);
1143 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1145 hres
= ITextRange_SetEnd(txtRge
, 3);
1146 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1148 hres
= ITextRange_GetStart(txtRge
, &start
);
1149 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1151 hres
= ITextRange_GetStart(txtRge
, NULL
);
1152 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1154 hres
= ITextRange_GetEnd(txtRge
, &end
);
1155 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1157 hres
= ITextRange_GetEnd(txtRge
, NULL
);
1158 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1160 ITextRange_Release(txtRge
);
1163 static void test_ITextSelection_GetStart_GetEnd(void)
1166 IRichEditOle
*reOle
= NULL
;
1167 ITextDocument
*txtDoc
= NULL
;
1168 ITextSelection
*txtSel
= NULL
;
1172 static const CHAR test_text1
[] = "TestSomeText";
1174 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
1175 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
1178 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1180 hres
= ITextSelection_GetStart(txtSel
, &start
);
1181 ok(hres
== S_OK
, "ITextSelection_GetStart\n");
1182 ok(start
== 2, "got wrong start value: %d\n", start
);
1184 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1185 ok(hres
== S_OK
, "ITextSelection_GetEnd\n");
1186 ok(end
== 5, "got wrong end value: %d\n", end
);
1189 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1191 hres
= ITextSelection_GetStart(txtSel
, &start
);
1192 ok(hres
== S_OK
, "ITextSelection_GetStart\n");
1193 ok(start
== 2, "got wrong start value: %d\n", start
);
1195 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1196 ok(hres
== S_OK
, "ITextSelection_GetEnd\n");
1197 ok(end
== 5, "got wrong end value: %d\n", end
);
1199 first
= 0; lim
= -1;
1200 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1202 hres
= ITextSelection_GetStart(txtSel
, &start
);
1203 ok(hres
== S_OK
, "ITextSelection_GetStart\n");
1204 ok(start
== 0, "got wrong start value: %d\n", start
);
1206 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1207 ok(hres
== S_OK
, "ITextSelection_GetEnd\n");
1208 ok(end
== 13, "got wrong end value: %d\n", end
);
1210 first
= 13; lim
= 13;
1211 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1213 hres
= ITextSelection_GetStart(txtSel
, &start
);
1214 ok(hres
== S_OK
, "ITextSelection_GetStart\n");
1215 ok(start
== 12, "got wrong start value: %d\n", start
);
1217 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1218 ok(hres
== S_OK
, "ITextSelection_GetEnd\n");
1219 ok(end
== 12, "got wrong end value: %d\n", end
);
1221 /* SetStart/SetEnd */
1222 hres
= ITextSelection_SetStart(txtSel
, 0);
1223 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1226 hres
= ITextSelection_SetStart(txtSel
, 0);
1227 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1229 hres
= ITextSelection_SetStart(txtSel
, 1);
1230 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1232 /* negative resets to 0, return value is S_FALSE when
1233 position wasn't changed */
1234 hres
= ITextSelection_SetStart(txtSel
, -1);
1235 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1237 hres
= ITextSelection_SetStart(txtSel
, -1);
1238 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1240 hres
= ITextSelection_SetStart(txtSel
, 0);
1241 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1244 hres
= ITextSelection_GetStart(txtSel
, &start
);
1245 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1246 ok(start
== 0, "got %d\n", start
);
1248 /* greater than initial end, but less than total char count */
1249 hres
= ITextSelection_SetStart(txtSel
, 1);
1250 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1252 hres
= ITextSelection_SetEnd(txtSel
, 3);
1253 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1255 hres
= ITextSelection_SetStart(txtSel
, 10);
1256 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1259 hres
= ITextSelection_GetStart(txtSel
, &start
);
1260 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1261 ok(start
== 10, "got %d\n", start
);
1264 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1265 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1266 ok(end
== 10, "got %d\n", end
);
1268 /* more that total text length */
1269 hres
= ITextSelection_SetStart(txtSel
, 50);
1270 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1273 hres
= ITextSelection_GetStart(txtSel
, &start
);
1274 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1275 ok(start
== 12, "got %d\n", start
);
1278 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1279 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1280 ok(end
== 12, "got %d\n", end
);
1283 hres
= ITextSelection_SetStart(txtSel
, 0);
1284 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1287 hres
= ITextSelection_SetEnd(txtSel
, 5);
1288 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1290 hres
= ITextSelection_SetEnd(txtSel
, 5);
1291 ok(hres
== S_FALSE
, "got 0x%08x\n", hres
);
1293 /* negative resets to 0 */
1294 hres
= ITextSelection_SetEnd(txtSel
, -1);
1295 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1298 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1299 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1300 ok(end
== 0, "got %d\n", end
);
1303 hres
= ITextSelection_GetStart(txtSel
, &start
);
1304 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1305 ok(start
== 0, "got %d\n", start
);
1307 /* greater than initial end, but less than total char count */
1308 hres
= ITextSelection_SetStart(txtSel
, 3);
1309 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1311 hres
= ITextSelection_SetEnd(txtSel
, 1);
1312 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1315 hres
= ITextSelection_GetStart(txtSel
, &start
);
1316 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1317 ok(start
== 1, "got %d\n", start
);
1320 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1321 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1322 ok(end
== 1, "got %d\n", end
);
1324 /* more than total count */
1325 hres
= ITextSelection_SetEnd(txtSel
, 50);
1326 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1329 hres
= ITextSelection_GetStart(txtSel
, &start
);
1330 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1331 ok(start
== 1, "got %d\n", start
);
1334 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1335 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1336 ok(end
== 13, "got %d\n", end
);
1339 hres
= ITextSelection_SetEnd(txtSel
, 0);
1340 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1343 hres
= ITextSelection_GetStart(txtSel
, &start
);
1344 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1345 ok(start
== 0, "got %d\n", start
);
1348 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1349 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1350 ok(end
== 0, "got %d\n", end
);
1352 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1354 /* detached selection */
1355 hres
= ITextSelection_GetStart(txtSel
, NULL
);
1356 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1358 hres
= ITextSelection_GetStart(txtSel
, &start
);
1359 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1361 hres
= ITextSelection_GetEnd(txtSel
, NULL
);
1362 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1364 hres
= ITextSelection_GetEnd(txtSel
, &end
);
1365 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1367 ITextSelection_Release(txtSel
);
1370 static void test_ITextRange_GetDuplicate(void)
1373 IRichEditOle
*reOle
= NULL
;
1374 ITextDocument
*txtDoc
= NULL
;
1375 ITextRange
*txtRge
= NULL
;
1376 ITextRange
*txtRgeDup
= NULL
;
1378 LONG first
, lim
, start
, end
;
1379 static const CHAR test_text1
[] = "TestSomeText";
1381 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1382 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
1384 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1385 ok(hres
== S_OK
, "ITextDocument_Range fails 0x%x.\n", hres
);
1387 hres
= ITextRange_GetDuplicate(txtRge
, &txtRgeDup
);
1388 ok(hres
== S_OK
, "ITextRange_GetDuplicate\n");
1389 ok(txtRgeDup
!= txtRge
, "A new pointer should be returned\n");
1390 hres
= ITextRange_GetStart(txtRgeDup
, &start
);
1391 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1392 ok(start
== first
, "got wrong value: %d\n", start
);
1393 hres
= ITextRange_GetEnd(txtRgeDup
, &end
);
1394 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1395 ok(end
== lim
, "got wrong value: %d\n", end
);
1397 ITextRange_Release(txtRgeDup
);
1399 hres
= ITextRange_GetDuplicate(txtRge
, NULL
);
1400 ok(hres
== E_INVALIDARG
, "ITextRange_GetDuplicate\n");
1402 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1404 hres
= ITextRange_GetDuplicate(txtRge
, NULL
);
1405 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1407 hres
= ITextRange_GetDuplicate(txtRge
, &txtRgeDup
);
1408 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1410 ITextRange_Release(txtRge
);
1413 static void test_ITextRange_Collapse(void)
1416 IRichEditOle
*reOle
= NULL
;
1417 ITextDocument
*txtDoc
= NULL
;
1418 ITextRange
*txtRge
= NULL
;
1420 LONG first
, lim
, start
, end
;
1421 static const CHAR test_text1
[] = "TestSomeText";
1423 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1424 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
1427 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1428 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1429 hres
= ITextRange_Collapse(txtRge
, tomTrue
);
1430 ok(hres
== S_OK
, "ITextRange_Collapse\n");
1431 hres
= ITextRange_GetStart(txtRge
, &start
);
1432 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1433 ok(start
== 4, "got wrong start value: %d\n", start
);
1434 hres
= ITextRange_GetEnd(txtRge
, &end
);
1435 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1436 ok(end
== 4, "got wrong end value: %d\n", end
);
1437 ITextRange_Release(txtRge
);
1439 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1440 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1441 hres
= ITextRange_Collapse(txtRge
, tomStart
);
1442 ok(hres
== S_OK
, "ITextRange_Collapse\n");
1443 hres
= ITextRange_GetStart(txtRge
, &start
);
1444 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1445 ok(start
== 4, "got wrong start value: %d\n", start
);
1446 hres
= ITextRange_GetEnd(txtRge
, &end
);
1447 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1448 ok(end
== 4, "got wrong end value: %d\n", end
);
1449 ITextRange_Release(txtRge
);
1451 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1452 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1453 hres
= ITextRange_Collapse(txtRge
, tomFalse
);
1454 ok(hres
== S_OK
, "ITextRange_Collapse\n");
1455 hres
= ITextRange_GetStart(txtRge
, &start
);
1456 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1457 ok(start
== 8, "got wrong start value: %d\n", start
);
1458 hres
= ITextRange_GetEnd(txtRge
, &end
);
1459 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1460 ok(end
== 8, "got wrong end value: %d\n", end
);
1461 ITextRange_Release(txtRge
);
1463 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1464 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1465 hres
= ITextRange_Collapse(txtRge
, tomEnd
);
1466 ok(hres
== S_OK
, "ITextRange_Collapse\n");
1467 hres
= ITextRange_GetStart(txtRge
, &start
);
1468 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1469 ok(start
== 8, "got wrong start value: %d\n", start
);
1470 hres
= ITextRange_GetEnd(txtRge
, &end
);
1471 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1472 ok(end
== 8, "got wrong end value: %d\n", end
);
1473 ITextRange_Release(txtRge
);
1475 /* tomStart is the default */
1476 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1477 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1478 hres
= ITextRange_Collapse(txtRge
, 256);
1479 ok(hres
== S_OK
, "ITextRange_Collapse\n");
1480 hres
= ITextRange_GetStart(txtRge
, &start
);
1481 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1482 ok(start
== 4, "got wrong start value: %d\n", start
);
1483 hres
= ITextRange_GetEnd(txtRge
, &end
);
1484 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1485 ok(end
== 4, "got wrong end value: %d\n", end
);
1486 ITextRange_Release(txtRge
);
1489 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1490 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1491 hres
= ITextRange_Collapse(txtRge
, tomEnd
);
1492 ok(hres
== S_FALSE
, "ITextRange_Collapse\n");
1493 hres
= ITextRange_GetStart(txtRge
, &start
);
1494 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1495 ok(start
== 6, "got wrong start value: %d\n", start
);
1496 hres
= ITextRange_GetEnd(txtRge
, &end
);
1497 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1498 ok(end
== 6, "got wrong end value: %d\n", end
);
1499 ITextRange_Release(txtRge
);
1502 hres
= ITextDocument_Range(txtDoc
, first
, lim
, &txtRge
);
1503 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1504 hres
= ITextRange_Collapse(txtRge
, tomStart
);
1505 ok(hres
== S_FALSE
, "ITextRange_Collapse\n");
1506 hres
= ITextRange_GetStart(txtRge
, &start
);
1507 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1508 ok(start
== 8, "got wrong start value: %d\n", start
);
1509 hres
= ITextRange_GetEnd(txtRge
, &end
);
1510 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1511 ok(end
== 8, "got wrong end value: %d\n", end
);
1513 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1515 hres
= ITextRange_Collapse(txtRge
, tomStart
);
1516 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1518 hres
= ITextRange_Collapse(txtRge
, tomUndefined
);
1519 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1521 ITextRange_Release(txtRge
);
1524 static void test_ITextSelection_Collapse(void)
1527 IRichEditOle
*reOle
= NULL
;
1528 ITextDocument
*txtDoc
= NULL
;
1529 ITextSelection
*txtSel
= NULL
;
1531 LONG first
, lim
, start
, end
;
1532 static const CHAR test_text1
[] = "TestSomeText";
1534 create_interfaces(&w
, &reOle
, &txtDoc
, &txtSel
);
1535 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
1538 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1539 hres
= ITextSelection_Collapse(txtSel
, tomTrue
);
1540 ok(hres
== S_OK
, "ITextSelection_Collapse\n");
1541 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1542 ok(start
== 4, "got wrong start value: %d\n", start
);
1543 ok(end
== 4, "got wrong end value: %d\n", end
);
1545 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1546 hres
= ITextSelection_Collapse(txtSel
, tomStart
);
1547 ok(hres
== S_OK
, "ITextSelection_Collapse\n");
1548 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1549 ok(start
== 4, "got wrong start value: %d\n", start
);
1550 ok(end
== 4, "got wrong end value: %d\n", end
);
1552 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1553 hres
= ITextSelection_Collapse(txtSel
, tomFalse
);
1554 ok(hres
== S_OK
, "ITextSelection_Collapse\n");
1555 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1556 ok(start
== 8, "got wrong start value: %d\n", start
);
1557 ok(end
== 8, "got wrong end value: %d\n", end
);
1559 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1560 hres
= ITextSelection_Collapse(txtSel
, tomEnd
);
1561 ok(hres
== S_OK
, "ITextSelection_Collapse\n");
1562 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1563 ok(start
== 8, "got wrong start value: %d\n", start
);
1564 ok(end
== 8, "got wrong end value: %d\n", end
);
1566 /* tomStart is the default */
1567 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1568 hres
= ITextSelection_Collapse(txtSel
, 256);
1569 ok(hres
== S_OK
, "ITextSelection_Collapse\n");
1570 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1571 ok(start
== 4, "got wrong start value: %d\n", start
);
1572 ok(end
== 4, "got wrong end value: %d\n", end
);
1575 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1576 hres
= ITextSelection_Collapse(txtSel
, tomEnd
);
1577 ok(hres
== S_FALSE
, "ITextSelection_Collapse\n");
1578 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1579 ok(start
== 6, "got wrong start value: %d\n", start
);
1580 ok(end
== 6, "got wrong end value: %d\n", end
);
1583 SendMessageA(w
, EM_SETSEL
, first
, lim
);
1584 hres
= ITextSelection_Collapse(txtSel
, tomStart
);
1585 ok(hres
== S_FALSE
, "ITextSelection_Collapse\n");
1586 SendMessageA(w
, EM_GETSEL
, (LPARAM
)&start
, (WPARAM
)&end
);
1587 ok(start
== 8, "got wrong start value: %d\n", start
);
1588 ok(end
== 8, "got wrong end value: %d\n", end
);
1590 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1592 hres
= ITextSelection_Collapse(txtSel
, tomStart
);
1593 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1595 hres
= ITextSelection_Collapse(txtSel
, tomUndefined
);
1596 ok(hres
== CO_E_RELEASED
, "got 0x%08x\n", hres
);
1598 ITextSelection_Release(txtSel
);
1601 static void test_GetClientSite(void)
1604 IRichEditOle
*reOle
= NULL
, *reOle1
= NULL
;
1605 ITextDocument
*txtDoc
= NULL
;
1606 IOleClientSite
*clientSite
= NULL
, *clientSite1
= NULL
, *clientSite2
= NULL
;
1607 IOleWindow
*oleWin
= NULL
, *oleWin1
= NULL
;
1608 IOleInPlaceSite
*olePlace
= NULL
, *olePlace1
= NULL
;
1610 LONG refcount1
, refcount2
;
1612 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1613 hres
= IRichEditOle_GetClientSite(reOle
, &clientSite
);
1614 ok(hres
== S_OK
, "IRichEditOle_QueryInterface: 0x%08x\n", hres
);
1615 EXPECT_REF(clientSite
, 1);
1617 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IRichEditOle
, (void **)&reOle1
);
1618 ok(hres
== E_NOINTERFACE
, "IOleClientSite_QueryInterface: %x\n", hres
);
1620 hres
= IRichEditOle_GetClientSite(reOle
, &clientSite1
);
1621 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
1622 ok(clientSite
!= clientSite1
, "got %p, %p\n", clientSite
, clientSite1
);
1623 IOleClientSite_Release(clientSite1
);
1625 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleClientSite
, (void **)&clientSite1
);
1626 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1627 ok(clientSite
== clientSite1
, "Should not return a new pointer.\n");
1628 EXPECT_REF(clientSite
, 2);
1630 /* IOleWindow interface */
1631 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleWindow
, (void **)&oleWin
);
1632 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1633 refcount1
= get_refcount((IUnknown
*)clientSite
);
1634 refcount2
= get_refcount((IUnknown
*)oleWin
);
1635 ok(refcount1
== refcount2
, "got wrong ref count.\n");
1637 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleWindow
, (void **)&oleWin1
);
1638 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1639 ok(oleWin
== oleWin1
, "Should not return a new pointer.\n");
1640 refcount1
= get_refcount((IUnknown
*)clientSite
);
1641 refcount2
= get_refcount((IUnknown
*)oleWin
);
1642 ok(refcount1
== refcount2
, "got wrong ref count.\n");
1644 hres
= IOleWindow_QueryInterface(oleWin
, &IID_IOleClientSite
, (void **)&clientSite2
);
1645 ok(hres
== S_OK
, "IOleWindow_QueryInterface: 0x%08x\n", hres
);
1646 ok(clientSite2
== clientSite1
, "got wrong pointer\n");
1648 /* IOleInPlaceSite interface */
1649 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleInPlaceSite
, (void **)&olePlace
);
1650 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1651 refcount1
= get_refcount((IUnknown
*)olePlace
);
1652 refcount2
= get_refcount((IUnknown
*)clientSite
);
1653 ok(refcount1
== refcount2
, "got wrong ref count.\n");
1655 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleInPlaceSite
, (void **)&olePlace1
);
1656 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1657 ok(olePlace
== olePlace1
, "Should not return a new pointer.\n");
1658 IOleInPlaceSite_Release(olePlace1
);
1660 hres
= IOleWindow_QueryInterface(oleWin
, &IID_IOleInPlaceSite
, (void **)&olePlace1
);
1661 ok(hres
== S_OK
, "IOleWindow_QueryInterface: 0x%08x\n", hres
);
1662 refcount1
= get_refcount((IUnknown
*)olePlace1
);
1663 refcount2
= get_refcount((IUnknown
*)oleWin
);
1664 ok(refcount1
== refcount2
, "got wrong ref count.\n");
1666 IOleInPlaceSite_Release(olePlace1
);
1667 IOleInPlaceSite_Release(olePlace
);
1668 IOleWindow_Release(oleWin1
);
1669 IOleWindow_Release(oleWin
);
1670 IOleClientSite_Release(clientSite2
);
1671 IOleClientSite_Release(clientSite1
);
1672 IOleClientSite_Release(clientSite
);
1673 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1676 static void test_IOleWindow_GetWindow(void)
1679 IRichEditOle
*reOle
= NULL
;
1680 ITextDocument
*txtDoc
= NULL
;
1681 IOleClientSite
*clientSite
= NULL
;
1682 IOleWindow
*oleWin
= NULL
;
1686 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1687 hres
= IRichEditOle_GetClientSite(reOle
, &clientSite
);
1688 ok(hres
== S_OK
, "IRichEditOle_QueryInterface: 0x%08x\n", hres
);
1690 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleWindow
, (void **)&oleWin
);
1691 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1692 hres
= IOleWindow_GetWindow(oleWin
, &hwnd
);
1693 ok(hres
== S_OK
, "IOleClientSite_GetWindow: 0x%08x\n", hres
);
1694 ok(w
== hwnd
, "got wrong pointer\n");
1696 hres
= IOleWindow_GetWindow(oleWin
, NULL
);
1697 ok(hres
== E_INVALIDARG
, "IOleClientSite_GetWindow: 0x%08x\n", hres
);
1699 IOleWindow_Release(oleWin
);
1700 IOleClientSite_Release(clientSite
);
1701 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1704 static void test_IOleInPlaceSite_GetWindow(void)
1707 IRichEditOle
*reOle
= NULL
;
1708 ITextDocument
*txtDoc
= NULL
;
1709 IOleClientSite
*clientSite
= NULL
;
1710 IOleInPlaceSite
*olePlace
= NULL
;
1714 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1715 hres
= IRichEditOle_GetClientSite(reOle
, &clientSite
);
1716 ok(hres
== S_OK
, "IRichEditOle_QueryInterface: 0x%08x\n", hres
);
1718 hres
= IOleClientSite_QueryInterface(clientSite
, &IID_IOleInPlaceSite
, (void **)&olePlace
);
1719 ok(hres
== S_OK
, "IOleClientSite_QueryInterface: 0x%08x\n", hres
);
1720 hres
= IOleInPlaceSite_GetWindow(olePlace
, &hwnd
);
1721 ok(hres
== S_OK
, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres
);
1722 ok(w
== hwnd
, "got wrong pointer.\n");
1724 hres
= IOleInPlaceSite_GetWindow(olePlace
, NULL
);
1725 ok(hres
== E_INVALIDARG
, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres
);
1727 IOleInPlaceSite_Release(olePlace
);
1728 IOleClientSite_Release(clientSite
);
1729 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
1732 static void test_GetFont(void)
1734 static const CHAR test_text1
[] = "TestSomeText";
1735 IRichEditOle
*reOle
= NULL
;
1736 ITextDocument
*doc
= NULL
;
1737 ITextRange
*range
= NULL
;
1738 ITextSelection
*selection
;
1739 ITextFont
*font
, *font2
;
1747 create_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
1748 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
1750 hr
= ITextDocument_GetSelection(doc
, &selection
);
1751 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1752 hr
= ITextSelection_GetFont(selection
, &font
);
1753 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1754 hr
= ITextSelection_GetFont(selection
, &font2
);
1755 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1756 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1757 ITextFont_Release(font2
);
1758 ITextFont_Release(font
);
1759 ITextSelection_Release(selection
);
1761 EXPECT_REF(reOle
, 3);
1764 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
1765 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1767 EXPECT_REF(reOle
, 3);
1769 EXPECT_REF(range
, 1);
1771 hr
= ITextRange_GetFont(range
, NULL
);
1772 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1774 hr
= ITextRange_GetFont(range
, &font
);
1775 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1777 EXPECT_REF(reOle
, 3);
1779 EXPECT_REF(range
, 2);
1780 EXPECT_REF(font
, 1);
1782 hr
= ITextRange_GetFont(range
, &font2
);
1783 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1784 ok(font
!= font2
, "got %p, %p\n", font
, font2
);
1786 EXPECT_REF(reOle
, 3);
1788 EXPECT_REF(range
, 3);
1789 EXPECT_REF(font
, 1);
1790 EXPECT_REF(font2
, 1);
1792 ITextFont_Release(font2
);
1794 /* set different font style within a range */
1795 hr
= ITextFont_GetItalic(font
, NULL
);
1796 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1798 hr
= ITextFont_GetSize(font
, NULL
);
1799 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1802 hr
= ITextFont_GetSize(font
, &size
);
1803 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1804 ok(size
> 0.0, "size %.2f\n", size
);
1807 hr
= ITextFont_GetLanguageID(font
, &value
);
1808 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1809 ok(value
== GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value
,
1810 GetSystemDefaultLCID());
1812 /* range is non-italic */
1814 hr
= ITextFont_GetItalic(font
, &value
);
1815 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1816 ok(value
== tomFalse
, "got %d\n", value
);
1818 cf
.cbSize
= sizeof(CHARFORMAT2A
);
1819 cf
.dwMask
= CFM_ITALIC
|CFM_SIZE
;
1820 cf
.dwEffects
= CFE_ITALIC
;
1823 SendMessageA(hwnd
, EM_SETSEL
, 2, 3);
1824 ret
= SendMessageA(hwnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
1825 ok(ret
, "got %d\n", ret
);
1827 /* now range is partially italicized */
1829 hr
= ITextFont_GetItalic(font
, &value
);
1830 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1831 ok(value
== tomUndefined
, "got %d\n", value
);
1834 hr
= ITextFont_GetSize(font
, &size
);
1835 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1836 ok(size
== tomUndefined
, "size %.2f\n", size
);
1838 ITextFont_Release(font
);
1839 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
1841 hr
= ITextRange_GetFont(range
, NULL
);
1842 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
1844 hr
= ITextRange_GetFont(range
, &font2
);
1845 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
1847 ITextRange_Release(range
);
1850 static void test_GetPara(void)
1852 static const CHAR test_text1
[] = "TestSomeText";
1853 IRichEditOle
*reOle
= NULL
;
1854 ITextDocument
*doc
= NULL
;
1855 ITextSelection
*selection
;
1856 ITextRange
*range
= NULL
;
1857 ITextPara
*para
, *para2
;
1861 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
1862 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
1864 EXPECT_REF(reOle
, 3);
1867 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
1868 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1870 EXPECT_REF(reOle
, 3);
1872 EXPECT_REF(range
, 1);
1874 hr
= ITextRange_GetPara(range
, NULL
);
1875 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1877 hr
= ITextRange_GetPara(range
, ¶
);
1878 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1880 EXPECT_REF(reOle
, 3);
1882 EXPECT_REF(range
, 2);
1883 EXPECT_REF(para
, 1);
1885 hr
= ITextRange_GetPara(range
, ¶2
);
1886 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1887 ok(para
!= para2
, "got %p, %p\n", para
, para2
);
1889 EXPECT_REF(reOle
, 3);
1891 EXPECT_REF(range
, 3);
1892 EXPECT_REF(para
, 1);
1893 EXPECT_REF(para2
, 1);
1895 ITextPara_Release(para
);
1896 ITextPara_Release(para2
);
1898 EXPECT_REF(reOle
, 3);
1900 EXPECT_REF(selection
, 2);
1902 hr
= ITextSelection_GetPara(selection
, ¶
);
1903 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1905 EXPECT_REF(reOle
, 3);
1907 EXPECT_REF(selection
, 3);
1908 EXPECT_REF(para
, 1);
1910 hr
= ITextSelection_GetPara(selection
, ¶2
);
1911 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1912 ok(para
!= para2
, "got %p, %p\n", para
, para2
);
1914 ITextPara_Release(para
);
1915 ITextPara_Release(para2
);
1916 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
1918 hr
= ITextRange_GetPara(range
, NULL
);
1919 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
1921 hr
= ITextRange_GetPara(range
, ¶
);
1922 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
1924 hr
= ITextSelection_GetPara(selection
, NULL
);
1925 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
1927 hr
= ITextSelection_GetPara(selection
, ¶
);
1928 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
1930 ITextSelection_Release(selection
);
1931 ITextRange_Release(range
);
1934 static void test_dispatch(void)
1936 static const WCHAR testnameW
[] = {'G','e','t','T','e','x','t',0};
1937 static const WCHAR testname2W
[] = {'T','e','x','t',0};
1938 IRichEditOle
*reOle
= NULL
;
1939 ITextDocument
*doc
= NULL
;
1940 ITextRange
*range
= NULL
;
1947 create_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
1950 hr
= ITextDocument_Range(doc
, 0, 0, &range
);
1951 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1952 ok(range
!= NULL
, "got %p\n", range
);
1955 nameW
= (WCHAR
*)testnameW
;
1956 hr
= ITextRange_GetIDsOfNames(range
, &IID_NULL
, &nameW
, 1, LOCALE_USER_DEFAULT
, &dispid
);
1957 ok(hr
== DISP_E_UNKNOWNNAME
, "got 0x%08x\n", hr
);
1958 ok(dispid
== DISPID_UNKNOWN
, "got %d\n", dispid
);
1961 nameW
= (WCHAR
*)testname2W
;
1962 hr
= ITextRange_GetIDsOfNames(range
, &IID_NULL
, &nameW
, 1, LOCALE_USER_DEFAULT
, &dispid
);
1963 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1964 ok(dispid
== DISPID_VALUE
, "got %d\n", dispid
);
1966 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
1968 /* try dispatch methods on detached range */
1969 hr
= ITextRange_GetTypeInfoCount(range
, &count
);
1970 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1973 nameW
= (WCHAR
*)testname2W
;
1974 hr
= ITextRange_GetIDsOfNames(range
, &IID_NULL
, &nameW
, 1, LOCALE_USER_DEFAULT
, &dispid
);
1975 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1976 ok(dispid
== DISPID_VALUE
, "got %d\n", dispid
);
1978 ITextRange_Release(range
);
1981 static void test_detached_font_getters(ITextFont
*font
, BOOL duplicate
)
1983 HRESULT hr
, hrexp
= duplicate
? S_OK
: CO_E_RELEASED
;
1988 hr
= ITextFont_GetBold(font
, NULL
);
1989 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1991 hr
= ITextFont_GetBold(font
, &value
);
1992 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
1994 hr
= ITextFont_GetForeColor(font
, NULL
);
1995 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1997 hr
= ITextFont_GetForeColor(font
, &value
);
1998 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2000 hr
= ITextFont_GetItalic(font
, NULL
);
2001 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2003 hr
= ITextFont_GetItalic(font
, &value
);
2004 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2006 hr
= ITextFont_GetLanguageID(font
, NULL
);
2007 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2009 hr
= ITextFont_GetLanguageID(font
, &value
);
2010 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2012 hr
= ITextFont_GetName(font
, NULL
);
2013 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2015 hr
= ITextFont_GetName(font
, &str
);
2016 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2018 hr
= ITextFont_GetSize(font
, NULL
);
2019 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2021 hr
= ITextFont_GetSize(font
, &size
);
2022 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2024 hr
= ITextFont_GetStrikeThrough(font
, NULL
);
2025 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2027 hr
= ITextFont_GetStrikeThrough(font
, &value
);
2028 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2030 hr
= ITextFont_GetSubscript(font
, NULL
);
2031 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2033 hr
= ITextFont_GetSubscript(font
, &value
);
2034 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2036 hr
= ITextFont_GetSuperscript(font
, NULL
);
2037 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2039 hr
= ITextFont_GetSuperscript(font
, &value
);
2040 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2042 hr
= ITextFont_GetUnderline(font
, NULL
);
2043 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2045 hr
= ITextFont_GetUnderline(font
, &value
);
2046 ok(hr
== hrexp
, "got 0x%08x\n", hr
);
2049 static void test_textfont_global_defaults(ITextFont
*font
)
2056 value
= tomUndefined
;
2057 hr
= ITextFont_GetAllCaps(font
, &value
);
2058 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2059 ok(value
== tomFalse
, "got %d\n", value
);
2061 value
= tomUndefined
;
2062 hr
= ITextFont_GetAnimation(font
, &value
);
2063 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2064 ok(value
== tomFalse
, "got %d\n", value
);
2066 value
= tomUndefined
;
2067 hr
= ITextFont_GetBackColor(font
, &value
);
2068 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2069 ok(value
== tomAutoColor
, "got %d\n", value
);
2071 value
= tomUndefined
;
2072 hr
= ITextFont_GetBold(font
, &value
);
2073 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2074 ok(value
== tomFalse
|| value
== tomTrue
, "got %d\n", value
);
2076 value
= tomUndefined
;
2077 hr
= ITextFont_GetEmboss(font
, &value
);
2078 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2079 ok(value
== tomFalse
, "got %d\n", value
);
2081 value
= tomUndefined
;
2082 hr
= ITextFont_GetForeColor(font
, &value
);
2083 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2084 ok(value
== tomAutoColor
, "got %d\n", value
);
2086 value
= tomUndefined
;
2087 hr
= ITextFont_GetHidden(font
, &value
);
2088 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2089 ok(value
== tomFalse
, "got %d\n", value
);
2091 value
= tomUndefined
;
2092 hr
= ITextFont_GetEngrave(font
, &value
);
2093 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2094 ok(value
== tomFalse
, "got %d\n", value
);
2096 value
= tomUndefined
;
2097 hr
= ITextFont_GetItalic(font
, &value
);
2098 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2099 ok(value
== tomFalse
, "got %d\n", value
);
2102 hr
= ITextFont_GetKerning(font
, &valuef
);
2103 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2104 ok(valuef
== 0.0, "got %.2f\n", valuef
);
2106 value
= tomUndefined
;
2107 hr
= ITextFont_GetLanguageID(font
, &value
);
2108 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2109 ok(value
== GetSystemDefaultLCID(), "got %d\n", value
);
2112 hr
= ITextFont_GetName(font
, &str
);
2113 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2114 ok(!lstrcmpW(sysW
, str
), "%s\n", wine_dbgstr_w(str
));
2117 value
= tomUndefined
;
2118 hr
= ITextFont_GetOutline(font
, &value
);
2119 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2120 ok(value
== tomFalse
, "got %d\n", value
);
2123 hr
= ITextFont_GetPosition(font
, &valuef
);
2124 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2125 ok(valuef
== 0.0, "got %.2f\n", valuef
);
2127 value
= tomUndefined
;
2128 hr
= ITextFont_GetProtected(font
, &value
);
2129 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2130 ok(value
== tomFalse
, "got %d\n", value
);
2132 value
= tomUndefined
;
2133 hr
= ITextFont_GetShadow(font
, &value
);
2134 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2135 ok(value
== tomFalse
, "got %d\n", value
);
2138 hr
= ITextFont_GetSize(font
, &valuef
);
2139 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2140 ok(valuef
>= 0.0, "got %.2f\n", valuef
);
2142 value
= tomUndefined
;
2143 hr
= ITextFont_GetSmallCaps(font
, &value
);
2144 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2145 ok(value
== tomFalse
, "got %d\n", value
);
2148 hr
= ITextFont_GetSpacing(font
, &valuef
);
2149 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2150 ok(valuef
== 0.0, "got %.2f\n", valuef
);
2152 value
= tomUndefined
;
2153 hr
= ITextFont_GetStrikeThrough(font
, &value
);
2154 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2155 ok(value
== tomFalse
, "got %d\n", value
);
2157 value
= tomUndefined
;
2158 hr
= ITextFont_GetSubscript(font
, &value
);
2159 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2160 ok(value
== tomFalse
, "got %d\n", value
);
2162 value
= tomUndefined
;
2163 hr
= ITextFont_GetSuperscript(font
, &value
);
2164 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2165 ok(value
== tomFalse
, "got %d\n", value
);
2167 value
= tomUndefined
;
2168 hr
= ITextFont_GetUnderline(font
, &value
);
2169 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2170 ok(value
== tomFalse
, "got %d\n", value
);
2172 value
= tomUndefined
;
2173 hr
= ITextFont_GetWeight(font
, &value
);
2174 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2175 ok(value
== FW_NORMAL
|| value
== FW_BOLD
, "got %d\n", value
);
2178 static void test_textfont_undefined(ITextFont
*font
)
2185 hr
= ITextFont_GetAllCaps(font
, &value
);
2186 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2187 ok(value
== tomUndefined
, "got %d\n", value
);
2190 hr
= ITextFont_GetAnimation(font
, &value
);
2191 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2192 ok(value
== tomUndefined
, "got %d\n", value
);
2195 hr
= ITextFont_GetBackColor(font
, &value
);
2196 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2197 ok(value
== tomUndefined
, "got %d\n", value
);
2200 hr
= ITextFont_GetBold(font
, &value
);
2201 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2202 ok(value
== tomUndefined
, "got %d\n", value
);
2205 hr
= ITextFont_GetEmboss(font
, &value
);
2206 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2207 ok(value
== tomUndefined
, "got %d\n", value
);
2210 hr
= ITextFont_GetForeColor(font
, &value
);
2211 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2212 ok(value
== tomUndefined
, "got %d\n", value
);
2215 hr
= ITextFont_GetHidden(font
, &value
);
2216 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2217 ok(value
== tomUndefined
, "got %d\n", value
);
2220 hr
= ITextFont_GetEngrave(font
, &value
);
2221 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2222 ok(value
== tomUndefined
, "got %d\n", value
);
2225 hr
= ITextFont_GetItalic(font
, &value
);
2226 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2227 ok(value
== tomUndefined
, "got %d\n", value
);
2230 hr
= ITextFont_GetKerning(font
, &valuef
);
2231 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2232 ok(valuef
== tomUndefined
, "got %.2f\n", valuef
);
2235 hr
= ITextFont_GetLanguageID(font
, &value
);
2236 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2237 ok(value
== tomUndefined
, "got %d\n", value
);
2240 hr
= ITextFont_GetOutline(font
, &value
);
2241 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2242 ok(value
== tomUndefined
, "got %d\n", value
);
2245 hr
= ITextFont_GetPosition(font
, &valuef
);
2246 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2247 ok(valuef
== tomUndefined
, "got %.2f\n", valuef
);
2250 hr
= ITextFont_GetProtected(font
, &value
);
2251 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2252 ok(value
== tomUndefined
, "got %d\n", value
);
2255 hr
= ITextFont_GetShadow(font
, &value
);
2256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2257 ok(value
== tomUndefined
, "got %d\n", value
);
2260 hr
= ITextFont_GetSize(font
, &valuef
);
2261 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2262 ok(valuef
== tomUndefined
, "got %.2f\n", valuef
);
2265 hr
= ITextFont_GetSmallCaps(font
, &value
);
2266 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2267 ok(value
== tomUndefined
, "got %d\n", value
);
2270 hr
= ITextFont_GetSpacing(font
, &valuef
);
2271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2272 ok(valuef
== tomUndefined
, "got %.2f\n", valuef
);
2275 hr
= ITextFont_GetStrikeThrough(font
, &value
);
2276 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2277 ok(value
== tomUndefined
, "got %d\n", value
);
2280 hr
= ITextFont_GetSubscript(font
, &value
);
2281 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2282 ok(value
== tomUndefined
, "got %d\n", value
);
2285 hr
= ITextFont_GetSuperscript(font
, &value
);
2286 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2287 ok(value
== tomUndefined
, "got %d\n", value
);
2290 hr
= ITextFont_GetUnderline(font
, &value
);
2291 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2292 ok(value
== tomUndefined
, "got %d\n", value
);
2295 hr
= ITextFont_GetWeight(font
, &value
);
2296 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2297 ok(value
== tomUndefined
, "got %d\n", value
);
2300 static inline FLOAT
twips_to_points(LONG value
)
2302 return value
* 72.0 / 1440;
2305 static void test_ITextFont(void)
2307 static const WCHAR arialW
[] = {'A','r','i','a','l',0};
2308 static const CHAR test_text1
[] = "TestSomeText";
2309 ITextFont
*font
, *font2
, *font3
;
2310 FLOAT size
, position
, kerning
;
2311 IRichEditOle
*reOle
= NULL
;
2312 ITextDocument
*doc
= NULL
;
2313 ITextRange
*range
= NULL
;
2321 create_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2322 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
2324 hr
= ITextDocument_Range(doc
, 0, 10, &range
);
2325 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2327 hr
= ITextRange_GetFont(range
, &font
);
2328 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2330 hr
= ITextFont_Reset(font
, tomUseTwips
);
2331 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2333 hr
= ITextFont_Reset(font
, tomUsePoints
);
2334 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2336 hr
= ITextFont_GetName(font
, NULL
);
2337 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2339 /* default font size unit is point */
2341 hr
= ITextFont_GetSize(font
, &size
);
2342 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2344 /* set to some non-zero values */
2345 hr
= ITextFont_SetPosition(font
, 20.0);
2346 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2348 hr
= ITextFont_SetKerning(font
, 10.0);
2349 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2352 hr
= ITextFont_GetPosition(font
, &position
);
2353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2356 hr
= ITextFont_GetKerning(font
, &kerning
);
2357 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2359 memset(&cf
, 0, sizeof(cf
));
2360 cf
.cbSize
= sizeof(cf
);
2361 cf
.dwMask
= CFM_SIZE
|CFM_OFFSET
|CFM_KERNING
;
2363 /* CHARFORMAT members are in twips */
2364 SendMessageA(hwnd
, EM_SETSEL
, 0, 10);
2365 ret
= SendMessageA(hwnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2366 ok(ret
, "got %d\n", ret
);
2367 ok(size
== twips_to_points(cf
.yHeight
), "got yHeight %d, size %.2f\n", cf
.yHeight
, size
);
2368 ok(position
== twips_to_points(cf
.yOffset
), "got yOffset %d, position %.2f\n", cf
.yOffset
, position
);
2369 ok(kerning
== twips_to_points(cf
.wKerning
), "got wKerning %d, kerning %.2f\n", cf
.wKerning
, kerning
);
2371 hr
= ITextFont_Reset(font
, tomUseTwips
);
2372 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2374 hr
= ITextFont_Reset(font
, tomUsePoints
);
2375 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2377 hr
= ITextFont_GetDuplicate(font
, &font2
);
2378 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2380 hr
= ITextFont_Reset(font2
, tomUseTwips
);
2381 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2383 hr
= ITextFont_Reset(font2
, tomUsePoints
);
2384 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2386 ITextFont_Release(font2
);
2388 /* default font name */
2390 hr
= ITextFont_GetName(font
, &str
);
2391 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2392 ok(!lstrcmpW(str
, sysW
), "got %s\n", wine_dbgstr_w(str
));
2395 /* change font name for an inner subrange */
2396 memset(&cf
, 0, sizeof(cf
));
2397 cf
.cbSize
= sizeof(cf
);
2398 cf
.dwMask
= CFM_FACE
;
2399 strcpy(cf
.szFaceName
, "Arial");
2401 SendMessageA(hwnd
, EM_SETSEL
, 3, 4);
2402 ret
= SendMessageA(hwnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2403 ok(ret
, "got %d\n", ret
);
2405 /* still original name */
2407 hr
= ITextFont_GetName(font
, &str
);
2408 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2409 ok(!lstrcmpW(str
, sysW
), "got %s\n", wine_dbgstr_w(str
));
2412 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
2413 ret
= SendMessageA(hwnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2414 ok(ret
, "got %d\n", ret
);
2417 hr
= ITextFont_GetName(font
, &str
);
2418 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2419 ok(!lstrcmpW(str
, sysW
), "got %s\n", wine_dbgstr_w(str
));
2422 /* name is returned for first position within a range */
2423 SendMessageA(hwnd
, EM_SETSEL
, 0, 1);
2424 ret
= SendMessageA(hwnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2425 ok(ret
, "got %d\n", ret
);
2428 hr
= ITextFont_GetName(font
, &str
);
2429 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2430 ok(!lstrcmpW(str
, arialW
), "got %s\n", wine_dbgstr_w(str
));
2433 /* GetDuplicate() */
2434 hr
= ITextFont_GetDuplicate(font
, NULL
);
2435 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2437 EXPECT_REF(range
, 2);
2439 hr
= ITextFont_GetDuplicate(font
, &font2
);
2440 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2441 EXPECT_REF(range
, 2);
2443 /* set whole range to italic */
2444 cf
.cbSize
= sizeof(CHARFORMAT2A
);
2445 cf
.dwMask
= CFM_ITALIC
;
2446 cf
.dwEffects
= CFE_ITALIC
;
2448 SendMessageA(hwnd
, EM_SETSEL
, 0, 10);
2449 ret
= SendMessageA(hwnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2450 ok(ret
, "got %d\n", ret
);
2453 hr
= ITextFont_GetItalic(font
, &value
);
2454 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2455 ok(value
== tomTrue
, "got %d\n", value
);
2457 /* duplicate retains original value */
2459 hr
= ITextFont_GetItalic(font2
, &value
);
2460 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2461 ok(value
== tomFalse
, "got %d\n", value
);
2463 /* get a duplicate from a cloned font */
2464 hr
= ITextFont_GetDuplicate(font2
, &font3
);
2465 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2466 ITextFont_Release(font3
);
2468 ITextRange_Release(range
);
2469 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2471 hr
= ITextFont_GetDuplicate(font
, NULL
);
2472 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2474 test_detached_font_getters(font
, FALSE
);
2475 test_detached_font_getters(font2
, TRUE
);
2477 /* get a duplicate of detached font */
2478 hr
= ITextFont_GetDuplicate(font2
, &font3
);
2479 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2480 ITextFont_Release(font3
);
2482 /* reset detached font to undefined */
2483 value
= tomUndefined
;
2484 hr
= ITextFont_GetBold(font2
, &value
);
2485 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2486 ok(value
!= tomUndefined
, "got %d\n", value
);
2488 /* reset to undefined for detached font */
2489 hr
= ITextFont_Reset(font2
, tomUndefined
);
2490 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2491 test_textfont_undefined(font2
);
2493 /* font is detached, default means global TOM defaults */
2494 hr
= ITextFont_Reset(font2
, tomDefault
);
2495 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2496 test_textfont_global_defaults(font2
);
2498 hr
= ITextFont_GetDuplicate(font2
, &font3
);
2499 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2500 test_textfont_global_defaults(font2
);
2502 hr
= ITextFont_Reset(font2
, tomApplyNow
);
2503 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2504 test_textfont_global_defaults(font2
);
2506 hr
= ITextFont_Reset(font2
, tomApplyLater
);
2507 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2508 test_textfont_global_defaults(font2
);
2510 hr
= ITextFont_Reset(font2
, tomTrackParms
);
2511 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2512 test_textfont_global_defaults(font2
);
2514 hr
= ITextFont_SetItalic(font2
, tomUndefined
);
2515 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2517 hr
= ITextFont_GetItalic(font2
, &value
);
2518 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2519 ok(value
== tomFalse
, "got %d\n", value
);
2521 hr
= ITextFont_Reset(font2
, tomCacheParms
);
2522 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2523 test_textfont_global_defaults(font2
);
2525 ITextFont_Release(font3
);
2526 ITextFont_Release(font2
);
2528 font2
= (void*)0xdeadbeef;
2529 hr
= ITextFont_GetDuplicate(font
, &font2
);
2530 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2531 ok(font2
== NULL
, "got %p\n", font2
);
2533 hr
= ITextFont_Reset(font
, tomDefault
);
2534 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2536 ITextFont_Release(font
);
2539 create_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2540 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
2542 hr
= ITextDocument_Range(doc
, 0, 10, &range
);
2543 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2545 hr
= ITextRange_GetFont(range
, &font
);
2546 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2548 value
= tomUndefined
;
2549 hr
= ITextFont_GetBold(font
, &value
);
2550 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2551 ok(value
!= tomUndefined
, "got %d\n", value
);
2553 /* reset to undefined for attached font */
2554 hr
= ITextFont_Reset(font
, tomUndefined
);
2555 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2557 value
= tomUndefined
;
2558 hr
= ITextFont_GetBold(font
, &value
);
2559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2560 ok(value
!= tomUndefined
, "got %d\n", value
);
2562 /* tomCacheParms/tomTrackParms */
2563 hr
= ITextFont_Reset(font
, tomCacheParms
);
2564 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2566 hr
= ITextFont_GetItalic(font
, &value
);
2567 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2568 ok(value
== tomFalse
, "got %d\n", value
);
2570 memset(&cf
, 0, sizeof(cf
));
2571 cf
.cbSize
= sizeof(CHARFORMAT2A
);
2572 cf
.dwMask
= CFM_ITALIC
;
2574 cf
.dwEffects
= CFE_ITALIC
;
2575 SendMessageA(hwnd
, EM_SETSEL
, 0, 10);
2576 ret
= SendMessageA(hwnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2577 ok(ret
, "got %d\n", ret
);
2579 /* still cached value */
2580 hr
= ITextFont_GetItalic(font
, &value
);
2581 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2582 ok(value
== tomFalse
, "got %d\n", value
);
2584 hr
= ITextFont_Reset(font
, tomTrackParms
);
2585 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2587 hr
= ITextFont_GetItalic(font
, &value
);
2588 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2589 ok(value
== tomTrue
, "got %d\n", value
);
2591 /* switch back to cache - value retained */
2592 hr
= ITextFont_Reset(font
, tomCacheParms
);
2593 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2595 hr
= ITextFont_GetItalic(font
, &value
);
2596 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2597 ok(value
== tomTrue
, "got %d\n", value
);
2600 hr
= ITextFont_Reset(font
, tomApplyLater
);
2601 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2603 hr
= ITextFont_SetItalic(font
, tomFalse
);
2604 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2606 hr
= ITextFont_GetItalic(font
, &value
);
2607 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2608 ok(value
== tomFalse
, "got %d\n", value
);
2611 SendMessageA(hwnd
, EM_SETSEL
, 0, 10);
2612 ret
= SendMessageA(hwnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2613 ok(ret
, "got %d\n", ret
);
2614 ok((cf
.dwEffects
& CFE_ITALIC
) == CFE_ITALIC
, "got 0x%08x\n", cf
.dwEffects
);
2616 hr
= ITextFont_Reset(font
, tomApplyNow
);
2617 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2620 SendMessageA(hwnd
, EM_SETSEL
, 0, 10);
2621 ret
= SendMessageA(hwnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2622 ok(ret
, "got %d\n", ret
);
2623 ok((cf
.dwEffects
& CFE_ITALIC
) == 0, "got 0x%08x\n", cf
.dwEffects
);
2625 hr
= ITextFont_SetItalic(font
, tomUndefined
);
2626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2628 hr
= ITextFont_GetItalic(font
, &value
);
2629 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2630 ok(value
== tomFalse
, "got %d\n", value
);
2632 hr
= ITextFont_SetItalic(font
, tomAutoColor
);
2633 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2636 SendMessageA(hwnd
, EM_SETSEL
, 0, 10);
2637 ret
= SendMessageA(hwnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
2638 ok(ret
, "got %d\n", ret
);
2639 ok((cf
.dwEffects
& CFE_ITALIC
) == 0, "got 0x%08x\n", cf
.dwEffects
);
2641 ITextRange_Release(range
);
2642 ITextFont_Release(font
);
2643 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2646 static void test_Delete(void)
2648 static const CHAR test_text1
[] = "TestSomeText";
2649 IRichEditOle
*reOle
= NULL
;
2650 ITextDocument
*doc
= NULL
;
2651 ITextRange
*range
, *range2
;
2656 create_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2657 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
2659 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
2660 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2662 hr
= ITextDocument_Range(doc
, 1, 2, &range2
);
2663 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2665 hr
= ITextRange_GetEnd(range
, &value
);
2666 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2667 ok(value
== 4, "got %d\n", value
);
2669 /* unit type doesn't matter is count is 0 */
2671 hr
= ITextRange_Delete(range2
, tomSentence
, 0, &value
);
2673 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2674 ok(value
== 1, "got %d\n", value
);
2677 hr
= ITextRange_Delete(range2
, tomCharacter
, 0, &value
);
2679 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2680 ok(value
== 0, "got %d\n", value
);
2682 hr
= ITextRange_GetEnd(range
, &value
);
2683 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2685 ok(value
== 3, "got %d\n", value
);
2687 hr
= ITextRange_GetStart(range2
, &value
);
2688 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2689 ok(value
== 1, "got %d\n", value
);
2691 hr
= ITextRange_GetEnd(range2
, &value
);
2692 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2694 ok(value
== 1, "got %d\n", value
);
2696 ITextRange_Release(range
);
2697 ITextRange_Release(range2
);
2698 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2701 static void test_SetText(void)
2703 static const CHAR test_text1
[] = "TestSomeText";
2704 static const WCHAR textW
[] = {'a','b','c','d','e','f','g','h','i',0};
2705 IRichEditOle
*reOle
= NULL
;
2706 ITextDocument
*doc
= NULL
;
2707 ITextRange
*range
, *range2
;
2713 create_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2714 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
2716 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
2717 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2719 hr
= ITextDocument_Range(doc
, 0, 4, &range2
);
2720 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2723 hr
= ITextRange_GetStart(range2
, &value
);
2724 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2725 ok(value
== 0, "got %d\n", value
);
2728 hr
= ITextRange_GetEnd(range2
, &value
);
2729 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2730 ok(value
== 4, "got %d\n", value
);
2732 hr
= ITextRange_SetText(range
, NULL
);
2733 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2736 hr
= ITextRange_GetEnd(range2
, &value
);
2737 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2738 ok(value
== 0, "got %d\n", value
);
2740 str
= SysAllocString(textW
);
2741 hr
= ITextRange_SetText(range
, str
);
2742 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2746 hr
= ITextRange_GetStart(range
, &value
);
2747 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2748 ok(value
== 0, "got %d\n", value
);
2751 hr
= ITextRange_GetEnd(range
, &value
);
2752 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2753 ok(value
== 9, "got %d\n", value
);
2756 hr
= ITextRange_GetStart(range2
, &value
);
2757 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2758 ok(value
== 0, "got %d\n", value
);
2761 hr
= ITextRange_GetEnd(range2
, &value
);
2762 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2763 ok(value
== 0, "got %d\n", value
);
2765 str
= SysAllocStringLen(NULL
, 0);
2766 hr
= ITextRange_SetText(range
, str
);
2767 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2769 hr
= ITextRange_GetEnd(range
, &value
);
2770 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2771 ok(value
== 0, "got %d\n", value
);
2774 ITextRange_Release(range2
);
2775 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2777 hr
= ITextRange_SetText(range
, NULL
);
2778 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2780 str
= SysAllocStringLen(NULL
, 0);
2781 hr
= ITextRange_SetText(range
, str
);
2782 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2785 ITextRange_Release(range
);
2788 static void test_InRange(void)
2790 static const CHAR test_text1
[] = "TestSomeText";
2791 ITextRange
*range
, *range2
, *range3
;
2792 IRichEditOle
*reOle
= NULL
;
2793 ITextDocument
*doc
= NULL
;
2794 ITextSelection
*selection
;
2799 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
2800 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
2801 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
2803 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
2804 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2806 hr
= ITextDocument_Range(doc
, 0, 4, &range2
);
2807 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2809 /* matches selection */
2810 hr
= ITextDocument_Range(doc
, 1, 2, &range3
);
2811 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2813 hr
= ITextRange_InRange(range
, NULL
, NULL
);
2814 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2817 hr
= ITextRange_InRange(range
, NULL
, &value
);
2818 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2819 ok(value
== tomFalse
, "got %d\n", value
);
2821 hr
= ITextRange_InRange(range
, range2
, NULL
);
2822 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2825 hr
= ITextRange_InRange(range
, range2
, &value
);
2826 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2827 ok(value
== tomTrue
, "got %d\n", value
);
2830 hr
= ITextSelection_InRange(selection
, NULL
, NULL
);
2831 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2834 hr
= ITextSelection_InRange(selection
, NULL
, &value
);
2835 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2836 ok(value
== tomFalse
, "got %d\n", value
);
2838 hr
= ITextSelection_InRange(selection
, range2
, NULL
);
2839 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2842 hr
= ITextSelection_InRange(selection
, range2
, &value
);
2843 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2844 ok(value
== tomFalse
, "got %d\n", value
);
2847 hr
= ITextSelection_InRange(selection
, range3
, &value
);
2848 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2849 ok(value
== tomFalse
, "got %d\n", value
);
2851 /* seems to work on ITextSelection ranges only */
2853 hr
= ITextSelection_InRange(selection
, (ITextRange
*)selection
, &value
);
2854 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2855 ok(value
== tomTrue
, "got %d\n", value
);
2857 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2859 hr
= ITextRange_InRange(range
, NULL
, NULL
);
2860 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2863 hr
= ITextRange_InRange(range
, NULL
, &value
);
2864 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2865 ok(value
== tomFalse
, "got %d\n", value
);
2867 hr
= ITextRange_InRange(range
, range2
, NULL
);
2868 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2871 hr
= ITextRange_InRange(range
, range2
, &value
);
2872 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2873 ok(value
== tomFalse
, "got %d\n", value
);
2876 hr
= ITextSelection_InRange(selection
, NULL
, NULL
);
2877 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2880 hr
= ITextSelection_InRange(selection
, NULL
, &value
);
2881 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2882 ok(value
== tomFalse
, "got %d\n", value
);
2884 hr
= ITextSelection_InRange(selection
, range2
, NULL
);
2885 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2888 hr
= ITextSelection_InRange(selection
, range2
, &value
);
2889 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2890 ok(value
== tomFalse
, "got %d\n", value
);
2892 ITextRange_Release(range
);
2893 ITextRange_Release(range2
);
2894 ITextRange_Release(range3
);
2895 ITextSelection_Release(selection
);
2898 static void test_ITextRange_IsEqual(void)
2900 static const CHAR test_text1
[] = "TestSomeText";
2901 ITextRange
*range
, *range2
, *range3
;
2902 IRichEditOle
*reOle
= NULL
;
2903 ITextDocument
*doc
= NULL
;
2904 ITextSelection
*selection
;
2909 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
2910 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
2911 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
2913 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
2914 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2916 hr
= ITextDocument_Range(doc
, 0, 4, &range2
);
2917 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2919 /* matches selection */
2920 hr
= ITextDocument_Range(doc
, 1, 2, &range3
);
2921 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2923 hr
= ITextRange_IsEqual(range
, NULL
, NULL
);
2924 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2927 hr
= ITextRange_IsEqual(range
, NULL
, &value
);
2928 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2929 ok(value
== tomFalse
, "got %d\n", value
);
2931 hr
= ITextRange_IsEqual(range
, range2
, NULL
);
2932 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2935 hr
= ITextRange_IsEqual(range
, range2
, &value
);
2936 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2937 ok(value
== tomTrue
, "got %d\n", value
);
2940 hr
= ITextRange_IsEqual(range
, range3
, &value
);
2941 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2942 ok(value
== tomFalse
, "got %d\n", value
);
2945 hr
= ITextSelection_IsEqual(selection
, NULL
, NULL
);
2946 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2949 hr
= ITextSelection_IsEqual(selection
, NULL
, &value
);
2950 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2951 ok(value
== tomFalse
, "got %d\n", value
);
2953 hr
= ITextSelection_IsEqual(selection
, range2
, NULL
);
2954 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2957 hr
= ITextSelection_IsEqual(selection
, range2
, &value
);
2958 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2959 ok(value
== tomFalse
, "got %d\n", value
);
2962 hr
= ITextSelection_IsEqual(selection
, range3
, &value
);
2963 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
2964 ok(value
== tomFalse
, "got %d\n", value
);
2966 /* seems to work on ITextSelection ranges only */
2968 hr
= ITextSelection_IsEqual(selection
, (ITextRange
*)selection
, &value
);
2969 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2970 ok(value
== tomTrue
, "got %d\n", value
);
2972 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
2974 hr
= ITextRange_IsEqual(range
, NULL
, NULL
);
2975 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2978 hr
= ITextRange_IsEqual(range
, NULL
, &value
);
2979 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2980 ok(value
== tomFalse
, "got %d\n", value
);
2982 hr
= ITextRange_IsEqual(range
, range2
, NULL
);
2983 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2986 hr
= ITextRange_IsEqual(range
, range2
, &value
);
2987 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2988 ok(value
== tomFalse
, "got %d\n", value
);
2991 hr
= ITextSelection_IsEqual(selection
, NULL
, NULL
);
2992 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2995 hr
= ITextSelection_IsEqual(selection
, NULL
, &value
);
2996 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
2997 ok(value
== tomFalse
, "got %d\n", value
);
2999 hr
= ITextSelection_IsEqual(selection
, range2
, NULL
);
3000 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3003 hr
= ITextSelection_IsEqual(selection
, range2
, &value
);
3004 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3005 ok(value
== tomFalse
, "got %d\n", value
);
3007 ITextRange_Release(range
);
3008 ITextRange_Release(range2
);
3009 ITextRange_Release(range3
);
3010 ITextSelection_Release(selection
);
3013 static void test_Select(void)
3015 static const CHAR test_text1
[] = "TestSomeText";
3016 IRichEditOle
*reOle
= NULL
;
3017 ITextDocument
*doc
= NULL
;
3018 ITextSelection
*selection
;
3024 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
3025 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3026 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3028 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
3029 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3031 hr
= ITextRange_Select(range
);
3032 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3035 hr
= ITextSelection_GetStart(selection
, &value
);
3036 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3037 ok(value
== 0, "got %d\n", value
);
3039 hr
= ITextRange_Select(range
);
3040 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3042 hr
= ITextSelection_Select(selection
);
3043 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3045 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
3047 hr
= ITextRange_Select(range
);
3048 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3050 hr
= ITextSelection_Select(selection
);
3051 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3053 ITextRange_Release(range
);
3054 ITextSelection_Release(selection
);
3057 static void test_GetStoryType(void)
3059 static const CHAR test_text1
[] = "TestSomeText";
3060 IRichEditOle
*reOle
= NULL
;
3061 ITextDocument
*doc
= NULL
;
3062 ITextSelection
*selection
;
3068 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
3069 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3070 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3072 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
3073 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3075 hr
= ITextRange_GetStoryType(range
, NULL
);
3076 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3078 value
= tomTextFrameStory
;
3079 hr
= ITextRange_GetStoryType(range
, &value
);
3080 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3081 ok(value
== tomUnknownStory
, "got %d\n", value
);
3083 hr
= ITextSelection_GetStoryType(selection
, NULL
);
3084 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3086 value
= tomTextFrameStory
;
3087 hr
= ITextSelection_GetStoryType(selection
, &value
);
3088 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3089 ok(value
== tomUnknownStory
, "got %d\n", value
);
3091 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
3093 hr
= ITextRange_GetStoryType(range
, NULL
);
3094 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3097 hr
= ITextRange_GetStoryType(range
, &value
);
3098 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3099 ok(value
== 123, "got %d\n", value
);
3101 hr
= ITextSelection_GetStoryType(selection
, NULL
);
3102 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3105 hr
= ITextSelection_GetStoryType(selection
, &value
);
3106 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3107 ok(value
== 123, "got %d\n", value
);
3109 ITextRange_Release(range
);
3110 ITextSelection_Release(selection
);
3113 static void test_SetFont(void)
3115 static const CHAR test_text1
[] = "TestSomeText";
3116 IRichEditOle
*reOle
= NULL
;
3117 ITextDocument
*doc
= NULL
;
3118 ITextSelection
*selection
;
3119 ITextRange
*range
, *range2
;
3120 ITextFont
*font
, *font2
;
3125 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
3126 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3127 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3129 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
3130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3132 hr
= ITextDocument_Range(doc
, 5, 2, &range2
);
3133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3135 EXPECT_REF(range
, 1);
3136 hr
= ITextRange_GetFont(range
, &font
);
3137 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3138 EXPECT_REF(range
, 2);
3140 EXPECT_REF(range2
, 1);
3141 hr
= ITextRange_GetFont(range2
, &font2
);
3142 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3143 EXPECT_REF(range2
, 2);
3145 hr
= ITextRange_SetFont(range
, NULL
);
3146 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3148 /* setting same font, no-op */
3149 EXPECT_REF(range
, 2);
3150 hr
= ITextRange_SetFont(range
, font
);
3151 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3152 EXPECT_REF(range
, 2);
3154 EXPECT_REF(range2
, 2);
3155 EXPECT_REF(range
, 2);
3156 hr
= ITextRange_SetFont(range
, font2
);
3157 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3158 EXPECT_REF(range2
, 2);
3159 EXPECT_REF(range
, 2);
3161 /* originally range 0-4 is non-italic */
3163 hr
= ITextFont_GetItalic(font
, &value
);
3164 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3165 ok(value
== tomFalse
, "got %d\n", value
);
3167 /* set range 5-2 to italic, then set this font to range 0-4 */
3168 hr
= ITextFont_SetItalic(font2
, tomTrue
);
3169 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3171 hr
= ITextRange_SetFont(range
, font2
);
3172 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3175 hr
= ITextFont_GetItalic(font
, &value
);
3176 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3177 ok(value
== tomTrue
, "got %d\n", value
);
3179 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
3181 hr
= ITextRange_SetFont(range
, NULL
);
3182 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3184 hr
= ITextRange_SetFont(range
, font
);
3185 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3187 hr
= ITextSelection_SetFont(selection
, NULL
);
3188 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3190 hr
= ITextSelection_SetFont(selection
, font
);
3191 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3193 ITextFont_Release(font
);
3194 ITextFont_Release(font2
);
3195 ITextRange_Release(range
);
3196 ITextRange_Release(range2
);
3197 ITextSelection_Release(selection
);
3200 static void fill_reobject_struct(REOBJECT
*reobj
, LONG cp
, LPOLEOBJECT poleobj
,
3201 LPSTORAGE pstg
, LPOLECLIENTSITE polesite
, LONG sizel_cx
,
3202 LONG sizel_cy
, DWORD aspect
, DWORD flags
, DWORD user
)
3204 reobj
->cbStruct
= sizeof(*reobj
);
3205 reobj
->clsid
= CLSID_NULL
;
3207 reobj
->poleobj
= poleobj
;
3209 reobj
->polesite
= polesite
;
3210 reobj
->sizel
.cx
= sizel_cx
;
3211 reobj
->sizel
.cy
= sizel_cy
;
3212 reobj
->dvaspect
= aspect
;
3213 reobj
->dwFlags
= flags
;
3214 reobj
->dwUser
= user
;
3217 #define CHECK_REOBJECT_STRUCT(reole,index,flags,cp,poleobj,pstg,polesite,user) \
3218 _check_reobject_struct(reole, index, flags, cp, poleobj, pstg, polesite, user, __LINE__)
3219 static void _check_reobject_struct(IRichEditOle
*reole
, LONG index
, DWORD flags
, LONG cp
,
3220 LPOLEOBJECT poleobj
, LPSTORAGE pstg
, LPOLECLIENTSITE polesite
, DWORD user
, int line
)
3225 reobj
.cbStruct
= sizeof(reobj
);
3227 hr
= IRichEditOle_GetObject(reole
, index
, &reobj
, flags
);
3228 ok(hr
== S_OK
, "IRichEditOle_GetObject failed: %#x.\n", hr
);
3229 ok_(__FILE__
,line
)(reobj
.poleobj
== poleobj
, "got wrong object interface.\n");
3230 ok_(__FILE__
,line
)(reobj
.pstg
== pstg
, "got wrong storage interface.\n");
3231 ok_(__FILE__
,line
)(reobj
.polesite
== polesite
, "got wrong site interface.\n");
3232 ok_(__FILE__
,line
)(reobj
.dwUser
== user
, "got wrong user-defined value.\n");
3235 #define INSERT_REOBJECT(reole,reobj,cp,user) \
3236 _insert_reobject(reole, reobj, cp, user, __LINE__)
3237 static void _insert_reobject(IRichEditOle
*reole
, REOBJECT
*reobj
, LONG cp
, DWORD user
, int line
)
3239 IOleClientSite
*clientsite
;
3241 hr
= IRichEditOle_GetClientSite(reole
, &clientsite
);
3242 ok_(__FILE__
,line
)(hr
== S_OK
, "IRichEditOle_GetClientSite got hr %#x.\n", hr
);
3243 fill_reobject_struct(reobj
, cp
, NULL
, NULL
, clientsite
, 10, 10, DVASPECT_CONTENT
, 0, user
);
3244 hr
= IRichEditOle_InsertObject(reole
, reobj
);
3245 ok_(__FILE__
,line
)(hr
== S_OK
, "IRichEditOle_InsertObject got hr %#x.\n", hr
);
3246 IOleClientSite_Release(clientsite
);
3249 static void test_InsertObject(void)
3251 static CHAR test_text1
[] = "abcdefg";
3252 IRichEditOle
*reole
= NULL
;
3253 ITextDocument
*doc
= NULL
;
3254 REOBJECT reo1
, reo2
, reo3
, received_reo
;
3257 const WCHAR
*expected_string
, *string
;
3258 const CHAR
*expected_stringA
;
3259 ITextSelection
*selection
;
3260 IDataObject
*dataobject
;
3261 TEXTRANGEA textrange
;
3262 FORMATETC formatetc
;
3263 CHARRANGE charrange
;
3264 GETTEXTEX gettextex
;
3265 STGMEDIUM stgmedium
;
3272 create_interfaces(&hwnd
, &reole
, &doc
, &selection
);
3273 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3275 hr
= IRichEditOle_InsertObject(reole
, NULL
);
3276 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3278 /* insert object1 in (0, 1)*/
3279 SendMessageA(hwnd
, EM_SETSEL
, 0, 1);
3280 INSERT_REOBJECT(reole
, &reo1
, REO_CP_SELECTION
, 1);
3281 count
= IRichEditOle_GetObjectCount(reole
);
3282 ok(count
== 1, "got wrong object count: %d\n", count
);
3284 /* insert object2 in (2, 3)*/
3285 SendMessageA(hwnd
, EM_SETSEL
, 2, 3);
3286 INSERT_REOBJECT(reole
, &reo2
, REO_CP_SELECTION
, 2);
3287 count
= IRichEditOle_GetObjectCount(reole
);
3288 ok(count
== 2, "got wrong object count: %d\n", count
);
3290 /* insert object3 in (1, 2)*/
3291 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3292 INSERT_REOBJECT(reole
, &reo3
, REO_CP_SELECTION
, 3);
3293 count
= IRichEditOle_GetObjectCount(reole
);
3294 ok(count
== 3, "got wrong object count: %d\n", count
);
3296 /* tests below show that order of rebject (from 0 to 2) is: reo1,reo3,reo2 */
3297 CHECK_REOBJECT_STRUCT(reole
, 0, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo1
.polesite
, 1);
3298 CHECK_REOBJECT_STRUCT(reole
, 1, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo3
.polesite
, 3);
3299 CHECK_REOBJECT_STRUCT(reole
, 2, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo2
.polesite
, 2);
3301 hr
= IRichEditOle_GetObject(reole
, 2, NULL
, REO_GETOBJ_ALL_INTERFACES
);
3302 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3304 received_reo
.cbStruct
= 0;
3305 hr
= IRichEditOle_GetObject(reole
, 2, &received_reo
, REO_GETOBJ_ALL_INTERFACES
);
3306 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3308 CHECK_REOBJECT_STRUCT(reole
, 2, REO_GETOBJ_PSTG
, 0, NULL
, NULL
, NULL
, 2);
3309 CHECK_REOBJECT_STRUCT(reole
, 2, REO_GETOBJ_POLESITE
, 0, NULL
, NULL
, reo2
.polesite
, 2);
3311 hr
= IRichEditOle_GetObject(reole
, 3, &received_reo
, REO_GETOBJ_POLESITE
);
3312 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3314 hr
= IRichEditOle_GetObject(reole
, 4, &received_reo
, REO_GETOBJ_POLESITE
);
3315 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3317 hr
= IRichEditOle_GetObject(reole
, 1024, &received_reo
, REO_GETOBJ_POLESITE
);
3318 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3320 hr
= IRichEditOle_GetObject(reole
, -10, &received_reo
, REO_GETOBJ_POLESITE
);
3321 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3323 /* received_reo will be zeroed before be used */
3324 received_reo
.cbStruct
= sizeof(received_reo
);
3325 received_reo
.polesite
= (IOleClientSite
*)0xdeadbeef;
3326 hr
= IRichEditOle_GetObject(reole
, 2, &received_reo
, REO_GETOBJ_NO_INTERFACES
);
3327 ok(hr
== S_OK
, "IRichEditOle_GetObject failed: 0x%08x\n", hr
);
3328 ok(received_reo
.polesite
== NULL
, "Got wrong site interface.\n");
3330 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_USE_CP
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo1
.polesite
, 1);
3331 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_USE_CP
, REO_GETOBJ_ALL_INTERFACES
, 1, NULL
, NULL
, reo3
.polesite
, 3);
3332 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_USE_CP
, REO_GETOBJ_ALL_INTERFACES
, 2, NULL
, NULL
, reo2
.polesite
, 2);
3334 received_reo
.cbStruct
= sizeof(received_reo
);
3335 received_reo
.polesite
= (IOleClientSite
*)0xdeadbeef;
3336 received_reo
.dwUser
= 4;
3337 received_reo
.cp
= 4;
3338 hr
= IRichEditOle_GetObject(reole
, REO_IOB_USE_CP
, &received_reo
, REO_GETOBJ_ALL_INTERFACES
);
3339 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3340 ok(received_reo
.polesite
== (IOleClientSite
*)0xdeadbeef, "Got wrong site interface.\n");
3341 ok(received_reo
.dwUser
== 4, "Got wrong user-defined value: %d.\n", received_reo
.dwUser
);
3343 SendMessageA(hwnd
, EM_SETSEL
, 0, 1);
3344 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo1
.polesite
, 1);
3346 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3347 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo3
.polesite
, 3);
3349 SendMessageA(hwnd
, EM_SETSEL
, 2, 3);
3350 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo2
.polesite
, 2);
3352 SendMessageA(hwnd
, EM_SETSEL
, 0, 2);
3353 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo1
.polesite
, 1);
3355 SendMessageA(hwnd
, EM_SETSEL
, 1, 3);
3356 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo3
.polesite
, 3);
3358 SendMessageA(hwnd
, EM_SETSEL
, 2, 0);
3359 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo1
.polesite
, 1);
3361 SendMessageA(hwnd
, EM_SETSEL
, 0, 6);
3362 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 0, NULL
, NULL
, reo1
.polesite
, 1);
3364 SendMessageA(hwnd
, EM_SETSEL
, 4, 5);
3365 received_reo
.cbStruct
= sizeof(received_reo
);
3366 received_reo
.cp
= 0;
3367 hr
= IRichEditOle_GetObject(reole
, REO_IOB_SELECTION
, &received_reo
, REO_GETOBJ_ALL_INTERFACES
);
3368 ok(hr
== E_INVALIDARG
, "IRichEditOle_GetObject should fail: 0x%08x\n", hr
);
3370 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3373 INSERT_REOBJECT(reole
, &reo1
, 3, 1);
3374 INSERT_REOBJECT(reole
, &reo2
, 5, 2);
3376 SendMessageW(hwnd
, EM_SETSEL
, 2, 3);
3377 result
= SendMessageW(hwnd
, EM_SELECTIONTYPE
, 0, 0);
3378 ok(result
== SEL_TEXT
, "Got selection type: %x.\n", result
);
3380 SendMessageW(hwnd
, EM_SETSEL
, 3, 4);
3381 result
= SendMessageW(hwnd
, EM_SELECTIONTYPE
, 0, 0);
3382 ok(result
== SEL_OBJECT
, "Got selection type: %x.\n", result
);
3383 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 1, NULL
, NULL
, reo1
.polesite
, 1);
3385 SendMessageW(hwnd
, EM_SETSEL
, 2, 4);
3386 result
= SendMessageW(hwnd
, EM_SELECTIONTYPE
, 0, 0);
3387 ok(result
== (SEL_TEXT
| SEL_OBJECT
), "Got selection type: %x.\n", result
);
3389 SendMessageW(hwnd
, EM_SETSEL
, 5, 6);
3390 CHECK_REOBJECT_STRUCT(reole
, REO_IOB_SELECTION
, REO_GETOBJ_ALL_INTERFACES
, 1, NULL
, NULL
, reo2
.polesite
, 2);
3392 expected_string
= L
"abc\xfffc""d\xfffc""efg";
3393 gettextex
.cb
= sizeof(buffer
);
3394 gettextex
.flags
= GT_DEFAULT
;
3395 gettextex
.codepage
= 1200;
3396 gettextex
.lpDefaultChar
= NULL
;
3397 gettextex
.lpUsedDefChar
= NULL
;
3398 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3399 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3400 todo_wine
ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3402 gettextex
.flags
= GT_RAWTEXT
;
3403 memset(buffer
, 0, sizeof(buffer
));
3404 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3405 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3406 todo_wine
ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3408 gettextex
.flags
= GT_NOHIDDENTEXT
;
3409 memset(buffer
, 0, sizeof(buffer
));
3410 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3411 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3412 todo_wine
ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3414 gettextex
.flags
= GT_SELECTION
;
3415 memset(buffer
, 0, sizeof(buffer
));
3416 SendMessageW(hwnd
, EM_SETSEL
, 0, -1);
3417 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3418 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3419 todo_wine
ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3421 expected_string
= L
"abc d efg";
3422 gettextex
.flags
= GT_USECRLF
;
3423 memset(buffer
, 0, sizeof(buffer
));
3424 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3425 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3426 ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3428 expected_stringA
= "abc d efg";
3429 memset(bufferA
, 0, sizeof(bufferA
));
3430 SendMessageA(hwnd
, EM_SETSEL
, 0, -1);
3431 result
= SendMessageA(hwnd
, EM_GETSELTEXT
, (WPARAM
)sizeof(bufferA
), (LPARAM
)bufferA
);
3432 ok(result
== strlen(expected_stringA
), "Got wrong length: %d.\n", result
);
3433 ok(!strcmp(bufferA
, expected_stringA
), "Got wrong content: %s.\n", bufferA
);
3435 memset(bufferA
, 0, sizeof(bufferA
));
3436 textrange
.lpstrText
= bufferA
;
3437 textrange
.chrg
.cpMin
= 0;
3438 textrange
.chrg
.cpMax
= 11;
3439 result
= SendMessageA(hwnd
, EM_GETTEXTRANGE
, 0, (LPARAM
)&textrange
);
3440 ok(result
== strlen(expected_stringA
), "Got wrong length: %d.\n", result
);
3441 ok(!strcmp(bufferA
, expected_stringA
), "Got wrong content: %s.\n", bufferA
);
3443 expected_string
= L
"abc\xfffc""d\xfffc""efg\r";
3444 hr
= ITextDocument_Range(doc
, 0, 11, &range
);
3445 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3446 hr
= ITextRange_GetText(range
, &bstr
);
3447 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3448 ok(lstrlenW(bstr
) == lstrlenW(expected_string
), "Got wrong length: %d.\n", lstrlenW(bstr
));
3449 todo_wine
ok(!lstrcmpW(bstr
, expected_string
), "Got text: %s.\n", wine_dbgstr_w(bstr
));
3450 SysFreeString(bstr
);
3451 hr
= ITextRange_SetRange(range
, 3, 4);
3452 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3453 hr
= ITextRange_GetChar(range
, &result
);
3454 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3455 todo_wine
ok(result
== 0xfffc, "Got char: %c\n", result
);
3456 ITextRange_Release(range
);
3458 SendMessageW(hwnd
, EM_SETSEL
, 0, -1);
3459 hr
= ITextSelection_GetText(selection
, &bstr
);
3460 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3461 ok(lstrlenW(bstr
) == lstrlenW(expected_string
), "Got wrong length: %d.\n", lstrlenW(bstr
));
3462 todo_wine
ok(!lstrcmpW(bstr
, expected_string
), "Got text: %s.\n", wine_dbgstr_w(bstr
));
3463 SysFreeString(bstr
);
3464 SendMessageW(hwnd
, EM_SETSEL
, 3, 4);
3466 hr
= ITextSelection_GetChar(selection
, &result
);
3467 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3468 todo_wine
ok(result
== 0xfffc, "Got char: %c\n", result
);
3470 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)"");
3471 result
= SendMessageW(hwnd
, EM_SETTEXTMODE
, (WPARAM
)TM_PLAINTEXT
, 0);
3472 ok(!result
, "Got result %x.\n", result
);
3474 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3475 INSERT_REOBJECT(reole
, &reo1
, 3, 1);
3476 INSERT_REOBJECT(reole
, &reo2
, 5, 2);
3478 expected_string
= L
"abc d efg";
3479 charrange
.cpMin
= 0;
3480 charrange
.cpMax
= 11;
3481 hr
= IRichEditOle_GetClipboardData(reole
, &charrange
, 1, &dataobject
);
3482 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3483 formatetc
.cfFormat
= CF_UNICODETEXT
;
3484 formatetc
.dwAspect
= DVASPECT_CONTENT
;
3485 formatetc
.ptd
= NULL
;
3486 formatetc
.tymed
= TYMED_HGLOBAL
;
3487 formatetc
.lindex
= -1;
3488 hr
= IDataObject_GetData(dataobject
, &formatetc
, &stgmedium
);
3489 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3490 string
= GlobalLock(stgmedium
.hGlobal
);
3491 ok(lstrlenW(string
) == lstrlenW(expected_string
), "Got wrong length: %d.\n", lstrlenW(string
));
3492 ok(!lstrcmpW(string
, expected_string
), "Got wrong content: %s.\n", debugstr_w(string
));
3493 GlobalUnlock(stgmedium
.hGlobal
);
3495 expected_string
= L
"abc\xfffc""d\xfffc""efg";
3496 gettextex
.cb
= sizeof(buffer
);
3497 gettextex
.flags
= GT_DEFAULT
;
3498 gettextex
.codepage
= 1200;
3499 gettextex
.lpDefaultChar
= NULL
;
3500 gettextex
.lpUsedDefChar
= NULL
;
3501 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3502 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3503 todo_wine
ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3505 gettextex
.flags
= GT_RAWTEXT
;
3506 memset(buffer
, 0, sizeof(buffer
));
3507 result
= SendMessageW(hwnd
, EM_GETTEXTEX
, (WPARAM
)&gettextex
, (LPARAM
)buffer
);
3508 ok(result
== lstrlenW(expected_string
), "Got wrong length: %d.\n", result
);
3509 todo_wine
ok(!lstrcmpW(buffer
, expected_string
), "Got wrong content: %s.\n", debugstr_w(buffer
));
3511 expected_stringA
= "abc d efg";
3512 memset(bufferA
, 0, sizeof(bufferA
));
3513 SendMessageA(hwnd
, EM_SETSEL
, 0, -1);
3514 result
= SendMessageA(hwnd
, EM_GETSELTEXT
, (WPARAM
)sizeof(bufferA
), (LPARAM
)bufferA
);
3515 ok(result
== strlen(expected_stringA
), "Got wrong length: %d.\n", result
);
3516 ok(!strcmp(bufferA
, expected_stringA
), "Got wrong content: %s.\n", bufferA
);
3518 memset(bufferA
, 0, sizeof(bufferA
));
3519 textrange
.lpstrText
= bufferA
;
3520 textrange
.chrg
.cpMin
= 0;
3521 textrange
.chrg
.cpMax
= 11;
3522 result
= SendMessageA(hwnd
, EM_GETTEXTRANGE
, 0, (LPARAM
)&textrange
);
3523 ok(result
== strlen(expected_stringA
), "Got wrong length: %d.\n", result
);
3524 ok(!strcmp(bufferA
, expected_stringA
), "Got wrong content: %s.\n", bufferA
);
3526 expected_string
= L
"abc\xfffc""d\xfffc""efg";
3527 hr
= ITextDocument_Range(doc
, 0, 11, &range
);
3528 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3529 hr
= ITextRange_GetText(range
, &bstr
);
3530 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3531 todo_wine
ok(lstrlenW(bstr
) == lstrlenW(expected_string
), "Got wrong length: %d.\n", lstrlenW(bstr
));
3532 todo_wine
ok(!lstrcmpW(bstr
, expected_string
), "Got text: %s.\n", wine_dbgstr_w(bstr
));
3533 SysFreeString(bstr
);
3534 hr
= ITextRange_SetRange(range
, 3, 4);
3535 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3536 hr
= ITextRange_GetChar(range
, &result
);
3537 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3538 todo_wine
ok(result
== 0xfffc, "Got char: %c\n", result
);
3539 ITextRange_Release(range
);
3541 SendMessageW(hwnd
, EM_SETSEL
, 0, -1);
3542 hr
= ITextSelection_GetText(selection
, &bstr
);
3543 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3544 todo_wine
ok(lstrlenW(bstr
) == lstrlenW(expected_string
), "Got wrong length: %d.\n", lstrlenW(bstr
));
3545 todo_wine
ok(!lstrcmpW(bstr
, expected_string
), "Got text: %s.\n", wine_dbgstr_w(bstr
));
3546 SysFreeString(bstr
);
3547 SendMessageW(hwnd
, EM_SETSEL
, 3, 4);
3549 hr
= ITextSelection_GetChar(selection
, &result
);
3550 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3551 todo_wine
ok(result
== 0xfffc, "Got char: %c\n", result
);
3553 release_interfaces(&hwnd
, &reole
, &doc
, &selection
);
3556 static void test_GetStoryLength(void)
3558 static const CHAR test_text1
[] = "TestSomeText";
3559 IRichEditOle
*reOle
= NULL
;
3560 ITextDocument
*doc
= NULL
;
3561 ITextSelection
*selection
;
3567 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
3568 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3569 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3571 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
3572 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3574 hr
= ITextRange_GetStoryLength(range
, NULL
);
3575 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3578 hr
= ITextRange_GetStoryLength(range
, &value
);
3579 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3580 ok(value
== 13, "got %d\n", value
);
3582 hr
= ITextSelection_GetStoryLength(selection
, NULL
);
3583 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3586 hr
= ITextSelection_GetStoryLength(selection
, &value
);
3587 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3588 ok(value
== 13, "got %d\n", value
);
3590 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)"");
3593 hr
= ITextRange_GetStoryLength(range
, &value
);
3594 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3595 ok(value
== 1, "got %d\n", value
);
3598 hr
= ITextSelection_GetStoryLength(selection
, &value
);
3599 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3600 ok(value
== 1, "got %d\n", value
);
3602 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
3604 hr
= ITextRange_GetStoryLength(range
, NULL
);
3605 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3608 hr
= ITextRange_GetStoryLength(range
, &value
);
3609 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3610 ok(value
== 100, "got %d\n", value
);
3612 hr
= ITextSelection_GetStoryLength(selection
, NULL
);
3613 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3616 hr
= ITextSelection_GetStoryLength(selection
, &value
);
3617 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3618 ok(value
== 100, "got %d\n", value
);
3620 ITextSelection_Release(selection
);
3621 ITextRange_Release(range
);
3624 static void test_ITextSelection_GetDuplicate(void)
3626 static const CHAR test_text1
[] = "TestSomeText";
3627 IRichEditOle
*reOle
= NULL
;
3628 ITextDocument
*doc
= NULL
;
3629 ITextSelection
*selection
, *sel2
;
3630 ITextRange
*range
, *range2
;
3636 create_interfaces(&hwnd
, &reOle
, &doc
, &selection
);
3637 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3638 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3640 hr
= ITextSelection_GetDuplicate(selection
, NULL
);
3641 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3643 EXPECT_REF(selection
, 2);
3645 hr
= ITextSelection_GetDuplicate(selection
, &range
);
3646 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3648 hr
= ITextSelection_GetDuplicate(selection
, &range2
);
3649 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3650 ok(range
!= range2
, "got %p, %p\n", range
, range2
);
3652 EXPECT_REF(selection
, 2);
3653 EXPECT_REF(range
, 1);
3654 EXPECT_REF(range2
, 1);
3656 ITextRange_Release(range2
);
3659 hr
= ITextRange_GetStart(range
, &value
);
3660 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3661 ok(value
== 1, "got %d\n", value
);
3664 hr
= ITextRange_GetEnd(range
, &value
);
3665 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3666 ok(value
== 2, "got %d\n", value
);
3668 SendMessageA(hwnd
, EM_SETSEL
, 2, 3);
3671 hr
= ITextRange_GetStart(range
, &value
);
3672 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3673 ok(value
== 1, "got %d\n", value
);
3676 hr
= ITextRange_GetEnd(range
, &value
);
3677 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3678 ok(value
== 2, "got %d\n", value
);
3680 hr
= ITextRange_QueryInterface(range
, &IID_ITextSelection
, (void**)&sel2
);
3681 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
3683 release_interfaces(&hwnd
, &reOle
, &doc
, NULL
);
3685 hr
= ITextSelection_GetDuplicate(selection
, NULL
);
3686 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3688 hr
= ITextSelection_GetDuplicate(selection
, &range
);
3689 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3691 hr
= ITextRange_GetFont(range
, &font
);
3692 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3694 ITextSelection_Release(selection
);
3695 ITextRange_Release(range
);
3698 #define RESET_RANGE(range,start,end) \
3699 _reset_range(range, start, end, __LINE__)
3700 static void _reset_range(ITextRange
*range
, LONG start
, LONG end
, int line
)
3704 hr
= ITextRange_SetStart(range
, start
);
3705 ok_(__FILE__
,line
)(hr
== S_OK
, "SetStart failed: 0x%08x\n", hr
);
3706 hr
= ITextRange_SetEnd(range
, end
);
3707 ok_(__FILE__
,line
)(hr
== S_OK
, "SetEnd failed: 0x%08x\n", hr
);
3710 #define CHECK_RANGE(range,expected_start,expected_end) \
3711 _check_range(range, expected_start, expected_end, __LINE__)
3712 static void _check_range(ITextRange
* range
, LONG expected_start
, LONG expected_end
, int line
)
3717 hr
= ITextRange_GetStart(range
, &value
);
3718 ok_(__FILE__
,line
)(hr
== S_OK
, "GetStart failed: 0x%08x\n", hr
);
3719 ok_(__FILE__
,line
)(value
== expected_start
, "Expected start %d got %d\n",
3720 expected_start
, value
);
3721 hr
= ITextRange_GetEnd(range
, &value
);
3722 ok_(__FILE__
,line
)(hr
== S_OK
, "GetEnd failed: 0x%08x\n", hr
);
3723 ok_(__FILE__
,line
)(value
== expected_end
, "Expected end %d got %d\n",
3724 expected_end
, value
);
3727 #define RESET_SELECTION(selection,start,end) \
3728 _reset_selection(selection, start, end, __LINE__)
3729 static void _reset_selection(ITextSelection
*selection
, LONG start
, LONG end
, int line
)
3733 hr
= ITextSelection_SetStart(selection
, start
);
3734 ok_(__FILE__
,line
)(hr
== S_OK
, "SetStart failed: 0x%08x\n", hr
);
3735 hr
= ITextSelection_SetEnd(selection
, end
);
3736 ok_(__FILE__
,line
)(hr
== S_OK
, "SetEnd failed: 0x%08x\n", hr
);
3739 #define CHECK_SELECTION(selection,expected_start,expected_end) \
3740 _check_selection(selection, expected_start, expected_end, __LINE__)
3741 static void _check_selection(ITextSelection
*selection
, LONG expected_start
, LONG expected_end
, int line
)
3746 hr
= ITextSelection_GetStart(selection
, &value
);
3747 ok_(__FILE__
,line
)(hr
== S_OK
, "GetStart failed: 0x%08x\n", hr
);
3748 ok_(__FILE__
,line
)(value
== expected_start
, "Expected start %d got %d\n",
3749 expected_start
, value
);
3750 hr
= ITextSelection_GetEnd(selection
, &value
);
3751 ok_(__FILE__
,line
)(hr
== S_OK
, "GetEnd failed: 0x%08x\n", hr
);
3752 ok_(__FILE__
,line
)(value
== expected_end
, "Expected end %d got %d\n",
3753 expected_end
, value
);
3756 static void test_ITextRange_SetRange(void)
3758 static const CHAR test_text1
[] = "TestSomeText";
3759 ITextDocument
*txtDoc
= NULL
;
3760 IRichEditOle
*reOle
= NULL
;
3761 ITextRange
*txtRge
= NULL
;
3765 create_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
3766 SendMessageA(w
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3767 ITextDocument_Range(txtDoc
, 0, 0, &txtRge
);
3769 hr
= ITextRange_SetRange(txtRge
, 2, 4);
3770 ok(hr
== S_OK
, "got 0x%08x.\n", hr
);
3771 CHECK_RANGE(txtRge
, 2, 4);
3773 hr
= ITextRange_SetRange(txtRge
, 2, 4);
3774 ok(hr
== S_FALSE
, "got 0x%08x.\n", hr
);
3775 CHECK_RANGE(txtRge
, 2, 4);
3777 hr
= ITextRange_SetRange(txtRge
, 4, 2);
3778 ok(hr
== S_FALSE
, "got 0x%08x.\n", hr
);
3779 CHECK_RANGE(txtRge
, 2, 4);
3781 hr
= ITextRange_SetRange(txtRge
, 14, 14);
3782 ok(hr
== S_OK
, "got 0x%08x.\n", hr
);
3783 CHECK_RANGE(txtRge
, 12, 12);
3785 hr
= ITextRange_SetRange(txtRge
, 15, 15);
3786 ok(hr
== S_FALSE
, "got 0x%08x.\n", hr
);
3787 CHECK_RANGE(txtRge
, 12, 12);
3789 hr
= ITextRange_SetRange(txtRge
, 14, 1);
3790 ok(hr
== S_OK
, "got 0x%08x.\n", hr
);
3791 CHECK_RANGE(txtRge
, 1, 13);
3793 hr
= ITextRange_SetRange(txtRge
, -1, 4);
3794 ok(hr
== S_OK
, "got 0x%08x.\n", hr
);
3795 CHECK_RANGE(txtRge
, 0, 4);
3797 ITextRange_Release(txtRge
);
3798 release_interfaces(&w
, &reOle
, &txtDoc
, NULL
);
3801 static void test_Expand(void)
3803 static const char test_text1
[] = "TestSomeText";
3804 IRichEditOle
*reole
= NULL
;
3805 ITextDocument
*doc
= NULL
;
3806 ITextSelection
*selection
;
3812 create_interfaces(&hwnd
, &reole
, &doc
, &selection
);
3813 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3814 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3816 hr
= ITextDocument_Range(doc
, 0, 4, &range
);
3817 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3819 hr
= ITextRange_Expand(range
, tomStory
, NULL
);
3820 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3821 CHECK_RANGE(range
, 0, 13);
3823 hr
= ITextSelection_Expand(selection
, tomStory
, NULL
);
3824 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3825 CHECK_SELECTION(selection
, 0, 13);
3827 RESET_RANGE(range
, 1, 2);
3828 RESET_SELECTION(selection
, 1, 2);
3831 hr
= ITextRange_Expand(range
, tomStory
, &value
);
3832 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3833 ok(value
== 12, "got %d\n", value
);
3834 CHECK_RANGE(range
, 0, 13);
3837 hr
= ITextSelection_Expand(selection
, tomStory
, &value
);
3838 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3839 ok(value
== 12, "got %d\n", value
);
3840 CHECK_SELECTION(selection
, 0, 13);
3842 release_interfaces(&hwnd
, &reole
, &doc
, NULL
);
3844 hr
= ITextRange_Expand(range
, tomStory
, NULL
);
3845 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3847 hr
= ITextRange_Expand(range
, tomStory
, &value
);
3848 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3850 hr
= ITextSelection_Expand(selection
, tomStory
, NULL
);
3851 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3853 hr
= ITextSelection_Expand(selection
, tomStory
, &value
);
3854 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3856 ITextSelection_Release(selection
);
3857 ITextRange_Release(range
);
3860 static void test_MoveEnd_story(void)
3862 static const char test_text1
[] = "Word1 Word2";
3863 IRichEditOle
*reole
= NULL
;
3864 ITextDocument
*doc
= NULL
;
3865 ITextSelection
*selection
;
3871 create_interfaces(&hwnd
, &reole
, &doc
, &selection
);
3872 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
3873 SendMessageA(hwnd
, EM_SETSEL
, 1, 2);
3875 hr
= ITextDocument_Range(doc
, 1, 2, &range
);
3876 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3878 hr
= ITextRange_MoveEnd(range
, tomStory
, 0, &delta
);
3879 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3880 ok(delta
== 0, "got %d\n", delta
);
3881 CHECK_RANGE(range
, 1, 2);
3883 hr
= ITextRange_MoveEnd(range
, tomStory
, -1, &delta
);
3884 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3885 ok(delta
== -1, "got %d\n", delta
);
3886 CHECK_RANGE(range
, 0, 0);
3888 hr
= ITextRange_MoveEnd(range
, tomStory
, 1, &delta
);
3889 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3890 ok(delta
== 1, "got %d\n", delta
);
3891 CHECK_RANGE(range
, 0, 12);
3893 hr
= ITextRange_MoveEnd(range
, tomStory
, 1, &delta
);
3894 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3895 ok(delta
== 0, "got %d\n", delta
);
3896 CHECK_RANGE(range
, 0, 12);
3898 RESET_RANGE(range
, 1, 2);
3900 hr
= ITextRange_MoveEnd(range
, tomStory
, 3, &delta
);
3901 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3902 ok(delta
== 1, "got %d\n", delta
);
3903 CHECK_RANGE(range
, 1, 12);
3905 RESET_RANGE(range
, 2, 3);
3907 hr
= ITextRange_MoveEnd(range
, tomStory
, -3, &delta
);
3908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3909 ok(delta
== -1, "got %d\n", delta
);
3910 CHECK_RANGE(range
, 0, 0);
3912 hr
= ITextRange_MoveEnd(range
, tomStory
, -1, &delta
);
3913 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3914 ok(delta
== 0, "got %d\n", delta
);
3915 CHECK_RANGE(range
, 0, 0);
3917 hr
= ITextSelection_MoveEnd(selection
, tomStory
, 0, &delta
);
3918 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3919 ok(delta
== 0, "got %d\n", delta
);
3920 CHECK_SELECTION(selection
, 1, 2);
3922 hr
= ITextSelection_MoveEnd(selection
, tomStory
, -1, &delta
);
3923 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3924 ok(delta
== -1, "got %d\n", delta
);
3925 CHECK_SELECTION(selection
, 0, 0);
3927 hr
= ITextSelection_MoveEnd(selection
, tomStory
, 1, &delta
);
3928 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3929 ok(delta
== 1, "got %d\n", delta
);
3930 CHECK_SELECTION(selection
, 0, 12);
3932 hr
= ITextSelection_MoveEnd(selection
, tomStory
, 1, &delta
);
3933 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3934 ok(delta
== 0, "got %d\n", delta
);
3935 CHECK_SELECTION(selection
, 0, 12);
3937 RESET_SELECTION(selection
, 1, 2);
3939 hr
= ITextSelection_MoveEnd(selection
, tomStory
, 3, &delta
);
3940 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3941 ok(delta
== 1, "got %d\n", delta
);
3942 CHECK_SELECTION(selection
, 1, 12);
3944 RESET_SELECTION(selection
, 2, 3);
3946 hr
= ITextSelection_MoveEnd(selection
, tomStory
, -3, &delta
);
3947 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3948 ok(delta
== -1, "got %d\n", delta
);
3949 CHECK_SELECTION(selection
, 0, 0);
3951 hr
= ITextSelection_MoveEnd(selection
, tomStory
, -1, &delta
);
3952 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3953 ok(delta
== 0, "got %d\n", delta
);
3954 CHECK_SELECTION(selection
, 0, 0);
3956 release_interfaces(&hwnd
, &reole
, &doc
, NULL
);
3958 hr
= ITextRange_MoveEnd(range
, tomStory
, 1, NULL
);
3959 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3961 hr
= ITextRange_MoveEnd(range
, tomStory
, 1, &delta
);
3962 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3964 hr
= ITextSelection_MoveEnd(selection
, tomStory
, 1, NULL
);
3965 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3967 hr
= ITextSelection_MoveEnd(selection
, tomStory
, 1, &delta
);
3968 ok(hr
== CO_E_RELEASED
, "got 0x%08x\n", hr
);
3970 ITextSelection_Release(selection
);
3971 ITextRange_Release(range
);
3974 static void test_character_movestart(ITextRange
*range
, int textlen
, int i
, int j
, LONG target
)
3978 LONG expected_delta
;
3979 LONG expected_start
= target
;
3981 if (expected_start
< 0)
3983 else if (expected_start
> textlen
)
3984 expected_start
= textlen
;
3985 expected_delta
= expected_start
- i
;
3986 hr
= ITextRange_SetRange(range
, i
, j
);
3987 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
3988 hr
= ITextRange_MoveStart(range
, tomCharacter
, target
- i
, &delta
);
3989 if (expected_start
== i
) {
3990 ok(hr
== S_FALSE
, "(%d,%d) move by %d got hr=0x%08x\n", i
, j
, target
- i
, hr
);
3991 ok(delta
== 0, "(%d,%d) move by %d got delta %d\n", i
, j
, target
- i
, delta
);
3992 CHECK_RANGE(range
, i
, j
);
3994 ok(hr
== S_OK
, "(%d,%d) move by %d got hr=0x%08x\n", i
, j
, target
- i
, hr
);
3995 ok(delta
== expected_delta
, "(%d,%d) move by %d got delta %d\n", i
, j
, target
- i
, delta
);
3996 if (expected_start
<= j
)
3997 CHECK_RANGE(range
, expected_start
, j
);
3999 CHECK_RANGE(range
, expected_start
, expected_start
);
4003 static void test_character_moveend(ITextRange
*range
, int textlen
, int i
, int j
, LONG target
)
4007 LONG expected_delta
;
4008 LONG expected_end
= target
;
4010 if (expected_end
< 0)
4012 else if (expected_end
> textlen
+ 1)
4013 expected_end
= textlen
+ 1;
4014 expected_delta
= expected_end
- j
;
4015 hr
= ITextRange_SetRange(range
, i
, j
);
4016 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
4017 hr
= ITextRange_MoveEnd(range
, tomCharacter
, target
- j
, &delta
);
4018 if (expected_end
== j
) {
4019 ok(hr
== S_FALSE
, "(%d,%d) move by %d got hr=0x%08x\n", i
, j
, target
- j
, hr
);
4020 ok(delta
== 0, "(%d,%d) move by %d got delta %d\n", i
, j
, target
- j
, delta
);
4021 CHECK_RANGE(range
, i
, j
);
4023 ok(hr
== S_OK
, "(%d,%d) move by %d got hr=0x%08x\n", i
, j
, target
- j
, hr
);
4024 ok(delta
== expected_delta
, "(%d,%d) move by %d got delta %d\n", i
, j
, target
- j
, delta
);
4025 if (i
<= expected_end
)
4026 CHECK_RANGE(range
, i
, expected_end
);
4028 CHECK_RANGE(range
, expected_end
, expected_end
);
4032 static void test_character_move(ITextRange
*range
, int textlen
, int i
, int j
, LONG target
)
4037 LONG expected_delta
;
4038 LONG expected_location
= target
;
4040 if (expected_location
< 0)
4041 expected_location
= 0;
4042 else if (expected_location
> textlen
)
4043 expected_location
= textlen
;
4046 move_by
= target
- i
;
4047 expected_delta
= expected_location
- i
;
4052 } else if (j
<= target
) {
4053 move_by
= target
- j
;
4054 expected_delta
= expected_location
- j
;
4060 /* There's no way to move to a point between start and end: */
4064 hr
= ITextRange_SetRange(range
, i
, j
);
4065 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
4066 hr
= ITextRange_Move(range
, tomCharacter
, move_by
, &delta
);
4067 if (expected_delta
== 0) {
4068 ok(hr
== S_FALSE
, "(%d,%d) move by %d got hr=0x%08x\n", i
, j
, move_by
, hr
);
4069 ok(delta
== 0, "(%d,%d) move by %d got delta %d\n", i
, j
, move_by
, delta
);
4070 CHECK_RANGE(range
, expected_location
, expected_location
);
4072 ok(hr
== S_OK
, "(%d,%d) move by %d got hr=0x%08x\n", i
, j
, move_by
, hr
);
4073 ok(delta
== expected_delta
, "(%d,%d) move by %d got delta %d\n", i
, j
, move_by
, delta
);
4074 CHECK_RANGE(range
, expected_location
, expected_location
);
4078 static void test_character_startof(ITextRange
*range
, int textlen
, int i
, int j
)
4083 hr
= ITextRange_SetRange(range
, i
, j
);
4084 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
4085 hr
= ITextRange_StartOf(range
, tomCharacter
, tomMove
, &delta
);
4087 ok(hr
== S_FALSE
, "(%d,%d) tomMove got hr=0x%08x\n", i
, j
, hr
);
4088 ok(delta
== 0, "(%d,%d) tomMove got delta %d\n", i
, j
, delta
);
4090 ok(hr
== S_OK
, "(%d,%d) tomMove got hr=0x%08x\n", i
, j
, hr
);
4091 ok(delta
== -1, "(%d,%d) tomMove got delta %d\n", i
, j
, delta
);
4093 CHECK_RANGE(range
, i
, i
);
4095 hr
= ITextRange_SetRange(range
, i
, j
);
4096 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
4097 hr
= ITextRange_StartOf(range
, tomCharacter
, tomExtend
, &delta
);
4098 ok(hr
== S_FALSE
, "(%d,%d) tomExtend got hr=0x%08x\n", i
, j
, hr
);
4099 ok(delta
== 0, "(%d,%d) tomExtend got delta %d\n", i
, j
, delta
);
4100 CHECK_RANGE(range
, i
, j
);
4103 static void test_character_endof(ITextRange
*range
, int textlen
, int i
, int j
)
4109 hr
= ITextRange_SetRange(range
, i
, j
);
4110 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
4111 hr
= ITextRange_EndOf(range
, tomCharacter
, tomMove
, &delta
);
4113 /* A character "end", apparently cannot be before the very first character */
4119 ok(hr
== S_FALSE
, "(%d,%d) tomMove got hr=0x%08x\n", i
, j
, hr
);
4120 ok(delta
== 0, "(%d,%d) tomMove got delta %d\n", i
, j
, delta
);
4122 ok(hr
== S_OK
, "(%d,%d) tomMove got hr=0x%08x\n", i
, j
, hr
);
4123 ok(delta
== 1, "(%d,%d) tomMove got delta %d\n", i
, j
, delta
);
4125 CHECK_RANGE(range
, end
, end
);
4127 hr
= ITextRange_SetRange(range
, i
, j
);
4128 ok(SUCCEEDED(hr
), "got 0x%08x\n", hr
);
4129 hr
= ITextRange_EndOf(range
, tomCharacter
, tomExtend
, &delta
);
4131 ok(hr
== S_FALSE
, "(%d,%d) tomExtend got hr=0x%08x\n", i
, j
, hr
);
4132 ok(delta
== 0, "(%d,%d) tomExtend got delta %d\n", i
, j
, delta
);
4134 ok(hr
== S_OK
, "(%d,%d) tomExtend got hr=0x%08x\n", i
, j
, hr
);
4135 ok(delta
== 1, "(%d,%d) tomExtend got delta %d\n", i
, j
, delta
);
4137 CHECK_RANGE(range
, i
, end
);
4140 static void test_character_movement(void)
4142 static const char test_text1
[] = "ab\n c";
4143 IRichEditOle
*reole
= NULL
;
4144 ITextDocument
*doc
= NULL
;
4146 ITextSelection
*selection
;
4150 const int textlen
= strlen(test_text1
);
4152 create_interfaces(&hwnd
, &reole
, &doc
, &selection
);
4153 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)test_text1
);
4155 hr
= ITextDocument_Range(doc
, 0, 0, &range
);
4156 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4158 /* Exhaustive test of every possible combination of (start,end) locations,
4159 * against every possible target location to move to. */
4160 for (i
= 0; i
<= textlen
; i
++) {
4161 for (j
= i
; j
<= textlen
; j
++) {
4163 for (target
= -2; target
<= textlen
+ 3; target
++) {
4164 test_character_moveend(range
, textlen
, i
, j
, target
);
4165 test_character_movestart(range
, textlen
, i
, j
, target
);
4166 test_character_move(range
, textlen
, i
, j
, target
);
4168 test_character_startof(range
, textlen
, i
, j
);
4169 test_character_endof(range
, textlen
, i
, j
);
4173 release_interfaces(&hwnd
, &reole
, &doc
, NULL
);
4174 ITextSelection_Release(selection
);
4175 ITextRange_Release(range
);
4178 #define CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 0);
4179 #define TODO_CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 1);
4180 static void _clipboard_range_contains(ITextRange
*range
, LONG start
, LONG end
, const char *expected
, int line
, int todo
)
4183 BOOL clipboard_open
;
4185 const char *clipboard_text
;
4187 hr
= ITextRange_SetRange(range
, start
, end
);
4188 ok_(__FILE__
,line
)(SUCCEEDED(hr
), "SetRange failed: 0x%08x\n", hr
);
4189 hr
= ITextRange_Copy(range
, NULL
);
4190 ok_(__FILE__
,line
)(hr
== S_OK
, "Copy failed: 0x%08x\n", hr
);
4192 clipboard_open
= OpenClipboard(NULL
);
4193 ok_(__FILE__
,line
)(clipboard_open
, "OpenClipboard failed: %d\n", GetLastError());
4194 global
= GetClipboardData(CF_TEXT
);
4195 ok_(__FILE__
,line
)(global
!= NULL
, "GetClipboardData failed: %p\n", global
);
4196 clipboard_text
= GlobalLock(global
);
4197 ok_(__FILE__
,line
)(clipboard_text
!= NULL
, "GlobalLock failed: %p\n", clipboard_text
);
4198 todo_wine_if(todo
) ok_(__FILE__
,line
)(!strcmp(expected
, clipboard_text
), "unexpected contents: %s\n", wine_dbgstr_a(clipboard_text
));
4199 GlobalUnlock(global
);
4203 static void test_clipboard(void)
4205 static const char text_in
[] = "ab\n c";
4206 IRichEditOle
*reole
= NULL
;
4207 ITextDocument
*doc
= NULL
;
4209 ITextSelection
*selection
;
4213 create_interfaces(&hwnd
, &reole
, &doc
, &selection
);
4214 SendMessageA(hwnd
, WM_SETTEXT
, 0, (LPARAM
)text_in
);
4216 hr
= ITextDocument_Range(doc
, 0, 0, &range
);
4217 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4219 CLIPBOARD_RANGE_CONTAINS(range
, 0, 5, "ab\r\n c")
4220 CLIPBOARD_RANGE_CONTAINS(range
, 0, 0, "ab\r\n c")
4221 CLIPBOARD_RANGE_CONTAINS(range
, 1, 1, "ab\r\n c")
4222 CLIPBOARD_RANGE_CONTAINS(range
, 0, 1, "a")
4223 CLIPBOARD_RANGE_CONTAINS(range
, 5, 6, "")
4225 /* Setting password char does not stop Copy */
4226 SendMessageA(hwnd
, EM_SETPASSWORDCHAR
, '*', 0);
4227 CLIPBOARD_RANGE_CONTAINS(range
, 0, 1, "a")
4229 /* Cut can be undone */
4230 hr
= ITextRange_SetRange(range
, 0, 1);
4231 ok(SUCCEEDED(hr
), "SetRange failed: 0x%08x\n", hr
);
4232 hr
= ITextRange_Cut(range
, NULL
);
4233 ok(hr
== S_OK
, "Cut failed: 0x%08x\n", hr
);
4234 CLIPBOARD_RANGE_CONTAINS(range
, 0, 4, "b\r\n c");
4235 hr
= ITextDocument_Undo(doc
, 1, NULL
);
4236 todo_wine
ok(hr
== S_OK
, "Undo failed: 0x%08x\n", hr
);
4237 TODO_CLIPBOARD_RANGE_CONTAINS(range
, 0, 5, "ab\r\n c");
4239 /* Cannot cut when read-only */
4240 SendMessageA(hwnd
, EM_SETREADONLY
, TRUE
, 0);
4241 hr
= ITextRange_SetRange(range
, 0, 1);
4242 ok(SUCCEEDED(hr
), "SetRange failed: 0x%08x\n", hr
);
4243 hr
= ITextRange_Cut(range
, NULL
);
4244 ok(hr
== E_ACCESSDENIED
, "got 0x%08x\n", hr
);
4246 release_interfaces(&hwnd
, &reole
, &doc
, NULL
);
4247 ITextSelection_Release(selection
);
4248 ITextRange_Release(range
);
4253 /* Must explicitly LoadLibrary(). The test has no references to functions in
4254 * RICHED20.DLL, so the linker doesn't actually link to it. */
4255 hmoduleRichEdit
= LoadLibraryA("riched20.dll");
4256 ok(hmoduleRichEdit
!= NULL
, "error: %d\n", (int) GetLastError());
4259 test_ITextDocument_Open();
4261 test_ITextSelection_GetChar();
4262 test_ITextSelection_GetStart_GetEnd();
4263 test_ITextSelection_Collapse();
4264 test_ITextDocument_Range();
4265 test_ITextRange_GetChar();
4266 test_ITextRange_ScrollIntoView();
4267 test_ITextRange_GetStart_GetEnd();
4268 test_ITextRange_SetRange();
4269 test_ITextRange_GetDuplicate();
4270 test_ITextRange_Collapse();
4271 test_GetClientSite();
4272 test_IOleWindow_GetWindow();
4273 test_IOleInPlaceSite_GetWindow();
4281 test_ITextRange_IsEqual();
4283 test_GetStoryType();
4285 test_InsertObject();
4286 test_GetStoryLength();
4287 test_ITextSelection_GetDuplicate();
4289 test_MoveEnd_story();
4290 test_character_movement();