1 /* 2 * oleacc tests 3 * 4 * Copyright 2008 Nikolay Sivov 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "wine/test.h" 24 #include <stdio.h> 25 26 #include "initguid.h" 27 #include <oleacc.h> 28 29 #define DEFINE_EXPECT(func) \ 30 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE 31 32 #define SET_EXPECT(func) \ 33 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0) 34 35 #define CHECK_EXPECT2(func) \ 36 do { \ 37 ok(expect_ ##func, "unexpected call " #func "\n"); \ 38 called_ ## func = TRUE; \ 39 }while(0) 40 41 #define CHECK_EXPECT(func) \ 42 do { \ 43 CHECK_EXPECT2(func); \ 44 expect_ ## func = FALSE; \ 45 }while(0) 46 47 #define CHECK_CALLED(func) \ 48 do { \ 49 ok(called_ ## func, "expected " #func "\n"); \ 50 expect_ ## func = called_ ## func = FALSE; \ 51 }while(0) 52 53 DEFINE_EXPECT(Accessible_QI_IEnumVARIANT); 54 DEFINE_EXPECT(Accessible_get_accChildCount); 55 DEFINE_EXPECT(Accessible_get_accChild); 56 57 static HANDLE (WINAPI *pGetProcessHandleFromHwnd)(HWND); 58 59 static BOOL init(void) 60 { 61 HMODULE oleacc = GetModuleHandleA("oleacc.dll"); 62 63 pGetProcessHandleFromHwnd = (void*)GetProcAddress(oleacc, "GetProcessHandleFromHwnd"); 64 if(!pGetProcessHandleFromHwnd) { 65 win_skip("GetProcessHandleFromHwnd not available\n"); 66 return FALSE; 67 } 68 69 return TRUE; 70 } 71 72 static HRESULT WINAPI Accessible_QueryInterface( 73 IAccessible *iface, REFIID riid, void **ppvObject) 74 { 75 if(IsEqualIID(riid, &IID_IEnumVARIANT)) { 76 CHECK_EXPECT(Accessible_QI_IEnumVARIANT); 77 return E_NOINTERFACE; 78 } 79 80 ok(0, "unexpected QI call: %s\n", wine_dbgstr_guid(riid)); 81 return E_NOTIMPL; 82 } 83 84 static ULONG WINAPI Accessible_AddRef(IAccessible *iface) 85 { 86 return 2; 87 } 88 89 static ULONG WINAPI Accessible_Release(IAccessible *iface) 90 { 91 return 1; 92 } 93 94 static HRESULT WINAPI Accessible_GetTypeInfoCount( 95 IAccessible *iface, UINT *pctinfo) 96 { 97 ok(0, "unexpected call\n"); 98 return E_NOTIMPL; 99 } 100 101 static HRESULT WINAPI Accessible_GetTypeInfo(IAccessible *iface, 102 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) 103 { 104 ok(0, "unexpected call\n"); 105 return E_NOTIMPL; 106 } 107 108 static HRESULT WINAPI Accessible_GetIDsOfNames(IAccessible *iface, REFIID riid, 109 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 110 { 111 ok(0, "unexpected call\n"); 112 return E_NOTIMPL; 113 } 114 115 static HRESULT WINAPI Accessible_Invoke(IAccessible *iface, DISPID dispIdMember, 116 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 117 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 118 { 119 ok(0, "unexpected call\n"); 120 return E_NOTIMPL; 121 } 122 123 static HRESULT WINAPI Accessible_get_accParent( 124 IAccessible *iface, IDispatch **ppdispParent) 125 { 126 ok(0, "unexpected call\n"); 127 return E_NOTIMPL; 128 } 129 130 static HRESULT WINAPI Accessible_get_accChildCount( 131 IAccessible *iface, LONG *pcountChildren) 132 { 133 CHECK_EXPECT(Accessible_get_accChildCount); 134 *pcountChildren = 1; 135 return S_OK; 136 } 137 138 static HRESULT WINAPI Accessible_get_accChild(IAccessible *iface, 139 VARIANT varChildID, IDispatch **ppdispChild) 140 { 141 CHECK_EXPECT(Accessible_get_accChild); 142 ok(V_VT(&varChildID) == VT_I4, "V_VT(&varChildID) = %d\n", V_VT(&varChildID)); 143 ok(V_I4(&varChildID) == 1, "V_I4(&varChildID) = %d\n", V_I4(&varChildID)); 144 145 *ppdispChild = NULL; 146 return S_OK; 147 } 148 149 static HRESULT WINAPI Accessible_get_accName(IAccessible *iface, 150 VARIANT varID, BSTR *pszName) 151 { 152 ok(0, "unexpected call\n"); 153 return E_NOTIMPL; 154 } 155 156 static HRESULT WINAPI Accessible_get_accValue(IAccessible *iface, 157 VARIANT varID, BSTR *pszValue) 158 { 159 ok(0, "unexpected call\n"); 160 return E_NOTIMPL; 161 } 162 163 static HRESULT WINAPI Accessible_get_accDescription(IAccessible *iface, 164 VARIANT varID, BSTR *pszDescription) 165 { 166 ok(0, "unexpected call\n"); 167 return E_NOTIMPL; 168 } 169 170 static HRESULT WINAPI Accessible_get_accRole(IAccessible *iface, 171 VARIANT varID, VARIANT *pvarRole) 172 { 173 ok(0, "unexpected call\n"); 174 return E_NOTIMPL; 175 } 176 177 static HRESULT WINAPI Accessible_get_accState(IAccessible *iface, 178 VARIANT varID, VARIANT *pvarState) 179 { 180 ok(0, "unexpected call\n"); 181 return E_NOTIMPL; 182 } 183 184 static HRESULT WINAPI Accessible_get_accHelp(IAccessible *iface, 185 VARIANT varID, BSTR *pszHelp) 186 { 187 ok(0, "unexpected call\n"); 188 return E_NOTIMPL; 189 } 190 191 static HRESULT WINAPI Accessible_get_accHelpTopic(IAccessible *iface, 192 BSTR *pszHelpFile, VARIANT varID, LONG *pidTopic) 193 { 194 ok(0, "unexpected call\n"); 195 return E_NOTIMPL; 196 } 197 198 static HRESULT WINAPI Accessible_get_accKeyboardShortcut(IAccessible *iface, 199 VARIANT varID, BSTR *pszKeyboardShortcut) 200 { 201 ok(0, "unexpected call\n"); 202 return E_NOTIMPL; 203 } 204 205 static HRESULT WINAPI Accessible_get_accFocus(IAccessible *iface, VARIANT *pvarID) 206 { 207 ok(0, "unexpected call\n"); 208 return E_NOTIMPL; 209 } 210 211 static HRESULT WINAPI Accessible_get_accSelection( 212 IAccessible *iface, VARIANT *pvarID) 213 { 214 ok(0, "unexpected call\n"); 215 return E_NOTIMPL; 216 } 217 218 static HRESULT WINAPI Accessible_get_accDefaultAction(IAccessible *iface, 219 VARIANT varID, BSTR *pszDefaultAction) 220 { 221 ok(0, "unexpected call\n"); 222 return E_NOTIMPL; 223 } 224 225 static HRESULT WINAPI Accessible_accSelect(IAccessible *iface, 226 LONG flagsSelect, VARIANT varID) 227 { 228 ok(0, "unexpected call\n"); 229 return E_NOTIMPL; 230 } 231 232 static HRESULT WINAPI Accessible_accLocation(IAccessible *iface, LONG *pxLeft, 233 LONG *pyTop, LONG *pcxWidth, LONG *pcyHeight, VARIANT varID) 234 { 235 ok(0, "unexpected call\n"); 236 return E_NOTIMPL; 237 } 238 239 static HRESULT WINAPI Accessible_accNavigate(IAccessible *iface, 240 LONG navDir, VARIANT varStart, VARIANT *pvarEnd) 241 { 242 ok(0, "unexpected call\n"); 243 return E_NOTIMPL; 244 } 245 246 static HRESULT WINAPI Accessible_accHitTest(IAccessible *iface, 247 LONG xLeft, LONG yTop, VARIANT *pvarID) 248 { 249 ok(0, "unexpected call\n"); 250 return E_NOTIMPL; 251 } 252 253 static HRESULT WINAPI Accessible_accDoDefaultAction( 254 IAccessible *iface, VARIANT varID) 255 { 256 ok(0, "unexpected call\n"); 257 return E_NOTIMPL; 258 } 259 260 static HRESULT WINAPI Accessible_put_accName(IAccessible *iface, 261 VARIANT varID, BSTR pszName) 262 { 263 ok(0, "unexpected call\n"); 264 return E_NOTIMPL; 265 } 266 267 static HRESULT WINAPI Accessible_put_accValue(IAccessible *iface, 268 VARIANT varID, BSTR pszValue) 269 { 270 ok(0, "unexpected call\n"); 271 return E_NOTIMPL; 272 } 273 274 static IAccessibleVtbl AccessibleVtbl = { 275 Accessible_QueryInterface, 276 Accessible_AddRef, 277 Accessible_Release, 278 Accessible_GetTypeInfoCount, 279 Accessible_GetTypeInfo, 280 Accessible_GetIDsOfNames, 281 Accessible_Invoke, 282 Accessible_get_accParent, 283 Accessible_get_accChildCount, 284 Accessible_get_accChild, 285 Accessible_get_accName, 286 Accessible_get_accValue, 287 Accessible_get_accDescription, 288 Accessible_get_accRole, 289 Accessible_get_accState, 290 Accessible_get_accHelp, 291 Accessible_get_accHelpTopic, 292 Accessible_get_accKeyboardShortcut, 293 Accessible_get_accFocus, 294 Accessible_get_accSelection, 295 Accessible_get_accDefaultAction, 296 Accessible_accSelect, 297 Accessible_accLocation, 298 Accessible_accNavigate, 299 Accessible_accHitTest, 300 Accessible_accDoDefaultAction, 301 Accessible_put_accName, 302 Accessible_put_accValue 303 }; 304 305 static IAccessible Accessible = {&AccessibleVtbl}; 306 307 static void test_getroletext(void) 308 { 309 INT ret, role; 310 CHAR buf[2], *buff; 311 WCHAR bufW[2], *buffW; 312 313 /* wrong role number */ 314 ret = GetRoleTextA(-1, NULL, 0); 315 ok(ret == 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret); 316 buf[0] = '*'; 317 ret = GetRoleTextA(-1, buf, 2); 318 ok(ret == 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret); 319 ok(buf[0] == 0, "GetRoleTextA doesn't return NULL char on wrong role number\n"); 320 buf[0] = '*'; 321 ret = GetRoleTextA(-1, buf, 0); 322 ok(ret == 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret); 323 ok(buf[0] == '*', "GetRoleTextA modified buffer on wrong role number\n"); 324 325 ret = GetRoleTextW(-1, NULL, 0); 326 ok(ret == 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret); 327 bufW[0] = '*'; 328 ret = GetRoleTextW(-1, bufW, 2); 329 ok(ret == 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret); 330 ok(bufW[0] == '\0', "GetRoleTextW doesn't return NULL char on wrong role number\n"); 331 bufW[0] = '*'; 332 ret = GetRoleTextW(-1, bufW, 0); 333 ok(ret == 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret); 334 335 /* zero role number - not documented */ 336 ret = GetRoleTextA(0, NULL, 0); 337 ok(ret > 0, "GetRoleTextA doesn't return (>0) for zero role number, got %d\n", ret); 338 ret = GetRoleTextW(0, NULL, 0); 339 ok(ret > 0, "GetRoleTextW doesn't return (>0) for zero role number, got %d\n", ret); 340 341 /* NULL buffer, return length */ 342 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, NULL, 0); 343 ok(ret > 0, "GetRoleTextA doesn't return length on NULL buffer, got %d\n", ret); 344 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, NULL, 1); 345 ok(ret > 0, "GetRoleTextA doesn't return length on NULL buffer, got %d\n", ret); 346 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, NULL, 0); 347 ok(ret > 0, "GetRoleTextW doesn't return length on NULL buffer, got %d\n", ret); 348 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, NULL, 1); 349 ok(ret > 0, "GetRoleTextW doesn't return length on NULL buffer, got %d\n", ret); 350 351 /* use a smaller buffer */ 352 bufW[0] = '*'; 353 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buf, 0); 354 ok(!ret, "GetRoleTextA doesn't return 0, got %d\n", ret); 355 ok(buf[0] == '*', "GetRoleTextA modified buffer\n"); 356 buffW = NULL; 357 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, (WCHAR*)&buffW, 0); 358 ok(ret, "GetRoleTextW doesn't return length\n"); 359 ok(buffW != NULL, "GetRoleTextW doesn't modify buffer\n"); 360 buf[0] = '*'; 361 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buf, 1); 362 ok(ret == 0, "GetRoleTextA returned wrong length\n"); 363 ok(buf[0] == '\0', "GetRoleTextA returned not zero-length buffer\n"); 364 buf[0] = '*'; 365 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buf, 2); 366 ok(!ret, "GetRoleTextA returned wrong length, got %d, expected 0\n", ret); 367 ok(!buf[0] || broken(buf[0]!='*') /* WinXP */, 368 "GetRoleTextA returned not zero-length buffer : (%c)\n", buf[0]); 369 370 bufW[0] = '*'; 371 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, bufW, 1); 372 ok(ret == 0, "GetRoleTextW returned wrong length, got %d, expected 1\n", ret); 373 ok(bufW[0] == '\0', "GetRoleTextW returned not zero-length buffer\n"); 374 bufW[1] = '*'; 375 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, bufW, 2); 376 ok(ret == 1, "GetRoleTextW returned wrong length, got %d, expected 1\n", ret); 377 ok(bufW[1] == '\0', "GetRoleTextW returned not zero-length buffer\n"); 378 379 /* use bigger buffer */ 380 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, NULL, 0); 381 buff = HeapAlloc(GetProcessHeap(), 0, 2*ret); 382 buff[2*ret-1] = '*'; 383 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buff, 2*ret); 384 ok(buff[2*ret-1] == '*', "GetRoleTextA shouldn't modify this part of buffer\n"); 385 HeapFree(GetProcessHeap(), 0, buff); 386 387 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, NULL, 0); 388 buffW = HeapAlloc(GetProcessHeap(), 0, 2*ret*sizeof(WCHAR)); 389 buffW[2*ret-1] = '*'; 390 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, buffW, 2*ret); 391 ok(buffW[2*ret-1] == '*', "GetRoleTextW shouldn't modify this part of buffer\n"); 392 HeapFree(GetProcessHeap(), 0, buffW); 393 394 /* check returned length for all roles */ 395 for(role = 0; role <= ROLE_SYSTEM_OUTLINEBUTTON; role++){ 396 CHAR buff2[100]; 397 WCHAR buff2W[100]; 398 399 /* NT4 and W2K don't clear the buffer on a nonexistent role in the A-call */ 400 memset(buff2, 0, sizeof(buff2)); 401 402 ret = GetRoleTextA(role, NULL, 0); 403 ok(ret > 0, "Expected the role to be present\n"); 404 405 GetRoleTextA(role, buff2, sizeof(buff2)); 406 ok(ret == lstrlenA(buff2), 407 "GetRoleTextA: returned length doesn't match returned buffer for role %d\n", role); 408 409 /* Win98 and WinMe don't clear the buffer on a nonexistent role in the W-call */ 410 memset(buff2W, 0, sizeof(buff2W)); 411 412 ret = GetRoleTextW(role, NULL, 0); 413 GetRoleTextW(role, buff2W, ARRAY_SIZE(buff2W)); 414 ok(ret == lstrlenW(buff2W), 415 "GetRoleTextW: returned length doesn't match returned buffer for role %d\n", role); 416 } 417 } 418 419 static void test_GetStateText(void) 420 { 421 WCHAR buf[1024], buf2[1024]; 422 char bufa[1024]; 423 void *ptr; 424 UINT ret, ret2; 425 int i; 426 427 ret2 = GetStateTextW(0, NULL, 1024); 428 ok(ret2, "GetStateText failed\n"); 429 430 ptr = NULL; 431 ret = GetStateTextW(0, (WCHAR*)&ptr, 0); 432 ok(ret == ret2, "got %d, expected %d\n", ret, ret2); 433 ok(ptr != NULL, "ptr was not changed\n"); 434 435 ret = GetStateTextW(0, buf, 1024); 436 ok(ret == ret2, "got %d, expected %d\n", ret, ret2); 437 ok(!memcmp(buf, ptr, ret*sizeof(WCHAR)), "got %s, expected %s\n", 438 wine_dbgstr_wn(buf, ret), wine_dbgstr_wn(ptr, ret)); 439 440 ret = GetStateTextW(0, buf, 1); 441 ok(!ret, "got %d, expected 0\n", ret); 442 ok(!buf[0], "buf[0] = '%c'\n", buf[0]); 443 444 for(i=0; i<31; i++) { 445 ret = GetStateTextW(1<<i, buf, 1024); 446 ok(ret, "%d) GetStateText failed\n", i); 447 } 448 ret = GetStateTextW(1u<<31, buf, 1024); 449 ok(!ret, "31) GetStateText succeeded: %d\n", ret); 450 451 ret = GetStateTextW(2, buf, 1024); 452 ok(ret, "GetStateText failed\n"); 453 ret2 = GetStateTextW(3, buf2, 1024); 454 ok(ret2, "GetStateText failed\n"); 455 ok(ret == ret2, "got %d, expected %d\n", ret2, ret); 456 ok(!memcmp(buf, buf2, ret*sizeof(WCHAR)), 457 "GetStateText(2,...) returned different data than GetStateText(3,...)\n"); 458 459 ret2 = GetStateTextA(0, NULL, 1024); 460 ok(ret2, "GetStateText failed\n"); 461 462 ptr = NULL; 463 ret = GetStateTextA(0, (CHAR*)&ptr, 0); 464 ok(!ret, "got %d\n", ret); 465 ok(ptr == NULL, "ptr was changed\n"); 466 467 ret = GetStateTextA(0, NULL, 0); 468 ok(ret == ret2, "got %d, expected %d\n", ret, ret2); 469 470 ret = GetStateTextA(0, bufa, 1024); 471 ok(ret == ret2, "got %d, expected %d\n", ret, ret2); 472 473 ret = GetStateTextA(0, bufa, 1); 474 ok(!ret, "got %d, expected 0\n", ret); 475 ok(!bufa[0], "bufa[0] = '%c'\n", bufa[0]); 476 477 for(i=0; i<31; i++) { 478 ret = GetStateTextA(1<<i, bufa, 1024); 479 ok(ret, "%d) GetStateText failed\n", i); 480 } 481 ret = GetStateTextA(1u<<31, bufa, 1024); 482 ok(!ret, "31) GetStateText succeeded: %d\n", ret); 483 } 484 485 static int Object_ref = 1; 486 static HRESULT WINAPI Object_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) 487 { 488 if(IsEqualIID(riid, &IID_IUnknown)) { 489 *ppv = iface; 490 IUnknown_AddRef(iface); 491 return S_OK; 492 } 493 return E_NOINTERFACE; 494 } 495 496 static ULONG WINAPI Object_AddRef(IUnknown *iface) 497 { 498 return InterlockedIncrement(&Object_ref); 499 } 500 501 static ULONG WINAPI Object_Release(IUnknown *iface) 502 { 503 return InterlockedDecrement(&Object_ref); 504 } 505 506 static IUnknownVtbl ObjectVtbl = { 507 Object_QueryInterface, 508 Object_AddRef, 509 Object_Release 510 }; 511 512 static IUnknown Object = {&ObjectVtbl}; 513 514 static void test_LresultFromObject(const char *name) 515 { 516 PROCESS_INFORMATION proc; 517 STARTUPINFOA startup; 518 char cmdline[MAX_PATH]; 519 IUnknown *unk; 520 HRESULT hres; 521 LRESULT lres; 522 523 lres = LresultFromObject(NULL, 0, 0); 524 ok(lres == E_INVALIDARG, "got %lx\n", lres); 525 526 hres = ObjectFromLresult(0, &IID_IUnknown, 0, (void**)&unk); 527 ok(hres == E_FAIL, "got %x\n", hres); 528 hres = ObjectFromLresult(0x10000, &IID_IUnknown, 0, (void**)&unk); 529 ok(hres == E_FAIL, "got %x\n", hres); 530 531 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref); 532 lres = LresultFromObject(&IID_IUnknown, 0, &Object); 533 ok(SUCCEEDED(lres), "got %lx\n", lres); 534 ok(Object_ref > 1, "Object_ref = %d\n", Object_ref); 535 536 hres = ObjectFromLresult(lres, &IID_IUnknown, 0, (void**)&unk); 537 ok(hres == S_OK, "hres = %x\n", hres); 538 ok(unk == &Object, "unk != &Object\n"); 539 IUnknown_Release(unk); 540 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref); 541 542 lres = LresultFromObject(&IID_IUnknown, 0, &Object); 543 ok(SUCCEEDED(lres), "got %lx\n", lres); 544 ok(Object_ref > 1, "Object_ref = %d\n", Object_ref); 545 546 sprintf(cmdline, "\"%s\" main ObjectFromLresult %s", name, wine_dbgstr_longlong(lres)); 547 memset(&startup, 0, sizeof(startup)); 548 startup.cb = sizeof(startup); 549 CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &proc); 550 winetest_wait_child_process(proc.hProcess); 551 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref); 552 } 553 554 static LRESULT WINAPI test_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 555 { 556 switch(msg) { 557 case WM_GETOBJECT: 558 if(lparam == OBJID_QUERYCLASSNAMEIDX) { 559 ok(!wparam, "wparam = %lx\n", wparam); 560 return 0; 561 } 562 563 ok(wparam==0xffffffff, "wparam = %lx\n", wparam); 564 if(lparam == (DWORD)OBJID_CURSOR) 565 return E_UNEXPECTED; 566 if(lparam == (DWORD)OBJID_CLIENT) 567 return LresultFromObject(&IID_IUnknown, wparam, &Object); 568 if(lparam == (DWORD)OBJID_WINDOW) 569 return 0; 570 571 ok(0, "unexpected (%ld)\n", lparam); 572 return 0; 573 } 574 575 return DefWindowProcA(hwnd, msg, wparam, lparam); 576 } 577 578 static BOOL register_window_class(void) 579 { 580 WNDCLASSA cls; 581 582 memset(&cls, 0, sizeof(cls)); 583 cls.lpfnWndProc = test_window_proc; 584 cls.lpszClassName = "oleacc_test"; 585 cls.hInstance = GetModuleHandleA(NULL); 586 587 return RegisterClassA(&cls); 588 } 589 590 static void unregister_window_class(void) 591 { 592 UnregisterClassA("oleacc_test", NULL); 593 } 594 595 static void test_AccessibleObjectFromWindow(void) 596 { 597 IUnknown *unk; 598 HRESULT hr; 599 HWND hwnd; 600 601 hr = AccessibleObjectFromWindow(NULL, OBJID_CURSOR, &IID_IUnknown, NULL); 602 ok(hr == E_INVALIDARG, "got %x\n", hr); 603 604 hr = AccessibleObjectFromWindow(NULL, OBJID_CURSOR, &IID_IUnknown, (void**)&unk); 605 todo_wine ok(hr == S_OK, "got %x\n", hr); 606 if(hr == S_OK) IUnknown_Release(unk); 607 608 hwnd = CreateWindowA("oleacc_test", "test", WS_OVERLAPPEDWINDOW, 609 0, 0, 0, 0, NULL, NULL, NULL, NULL); 610 ok(hwnd != NULL, "CreateWindow failed\n"); 611 612 hr = AccessibleObjectFromWindow(hwnd, OBJID_CURSOR, &IID_IUnknown, (void**)&unk); 613 ok(hr == E_UNEXPECTED, "got %x\n", hr); 614 615 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref); 616 hr = AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, &IID_IUnknown, (void**)&unk); 617 ok(hr == S_OK, "got %x\n", hr); 618 ok(Object_ref == 2, "Object_ref = %d\n", Object_ref); 619 IUnknown_Release(unk); 620 621 DestroyWindow(hwnd); 622 } 623 624 static void test_GetProcessHandleFromHwnd(void) 625 { 626 HANDLE proc; 627 HWND hwnd; 628 629 proc = pGetProcessHandleFromHwnd(NULL); 630 ok(!proc, "proc = %p\n", proc); 631 632 hwnd = CreateWindowA("static", "", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); 633 ok(hwnd != NULL, "CreateWindow failed\n"); 634 635 proc = pGetProcessHandleFromHwnd(hwnd); 636 ok(proc != NULL, "proc == NULL\n"); 637 CloseHandle(proc); 638 639 DestroyWindow(hwnd); 640 } 641 642 static void test_AccessibleChildren(IAccessible *acc) 643 { 644 VARIANT children[3]; 645 LONG count; 646 HRESULT hr; 647 648 count = -1; 649 hr = AccessibleChildren(NULL, 0, 0, children, &count); 650 ok(hr == E_INVALIDARG, "AccessibleChildren returned %x\n", hr); 651 ok(count == -1, "count = %d\n", count); 652 hr = AccessibleChildren(acc, 0, 0, NULL, &count); 653 ok(hr == E_INVALIDARG, "AccessibleChildren returned %x\n", hr); 654 ok(count == -1, "count = %d\n", count); 655 hr = AccessibleChildren(acc, 0, 0, children, NULL); 656 ok(hr == E_INVALIDARG, "AccessibleChildren returned %x\n", hr); 657 658 if(acc == &Accessible) { 659 SET_EXPECT(Accessible_QI_IEnumVARIANT); 660 SET_EXPECT(Accessible_get_accChildCount); 661 } 662 hr = AccessibleChildren(acc, 0, 0, children, &count); 663 ok(hr == S_OK, "AccessibleChildren returned %x\n", hr); 664 if(acc == &Accessible) { 665 CHECK_CALLED(Accessible_QI_IEnumVARIANT); 666 CHECK_CALLED(Accessible_get_accChildCount); 667 } 668 ok(!count, "count = %d\n", count); 669 count = -1; 670 if(acc == &Accessible) { 671 SET_EXPECT(Accessible_QI_IEnumVARIANT); 672 SET_EXPECT(Accessible_get_accChildCount); 673 } 674 hr = AccessibleChildren(acc, 5, 0, children, &count); 675 ok(hr == S_OK, "AccessibleChildren returned %x\n", hr); 676 if(acc == &Accessible) { 677 CHECK_CALLED(Accessible_QI_IEnumVARIANT); 678 CHECK_CALLED(Accessible_get_accChildCount); 679 } 680 ok(!count, "count = %d\n", count); 681 682 memset(children, 0xfe, sizeof(children)); 683 V_VT(children) = VT_DISPATCH; 684 if(acc == &Accessible) { 685 SET_EXPECT(Accessible_QI_IEnumVARIANT); 686 SET_EXPECT(Accessible_get_accChildCount); 687 SET_EXPECT(Accessible_get_accChild); 688 } 689 hr = AccessibleChildren(acc, 0, 1, children, &count); 690 ok(hr == S_OK, "AccessibleChildren returned %x\n", hr); 691 if(acc == &Accessible) { 692 CHECK_CALLED(Accessible_QI_IEnumVARIANT); 693 CHECK_CALLED(Accessible_get_accChildCount); 694 CHECK_CALLED(Accessible_get_accChild); 695 696 ok(V_VT(children) == VT_I4, "V_VT(children) = %d\n", V_VT(children)); 697 ok(V_I4(children) == 1, "V_I4(children) = %d\n", V_I4(children)); 698 }else { 699 ok(V_VT(children) == VT_DISPATCH, "V_VT(children) = %d\n", V_VT(children)); 700 IDispatch_Release(V_DISPATCH(children)); 701 } 702 ok(count == 1, "count = %d\n", count); 703 704 if(acc == &Accessible) { 705 SET_EXPECT(Accessible_QI_IEnumVARIANT); 706 SET_EXPECT(Accessible_get_accChildCount); 707 SET_EXPECT(Accessible_get_accChild); 708 } 709 hr = AccessibleChildren(acc, 0, 3, children, &count); 710 ok(hr == S_FALSE, "AccessibleChildren returned %x\n", hr); 711 if(acc == &Accessible) { 712 CHECK_CALLED(Accessible_QI_IEnumVARIANT); 713 CHECK_CALLED(Accessible_get_accChildCount); 714 CHECK_CALLED(Accessible_get_accChild); 715 716 ok(V_VT(children) == VT_I4, "V_VT(children) = %d\n", V_VT(children)); 717 ok(V_I4(children) == 1, "V_I4(children) = %d\n", V_I4(children)); 718 }else { 719 ok(V_VT(children) == VT_DISPATCH, "V_VT(children) = %d\n", V_VT(children)); 720 IDispatch_Release(V_DISPATCH(children)); 721 } 722 ok(count == 1, "count = %d\n", count); 723 ok(V_VT(children+1) == VT_EMPTY, "V_VT(children+1) = %d\n", V_VT(children+1)); 724 ok(V_VT(children+2) == VT_EMPTY, "V_VT(children+2) = %d\n", V_VT(children+2)); 725 } 726 727 static void test_default_client_accessible_object(void) 728 { 729 static const WCHAR testW[] = {'t','e','s','t',' ','t',' ','&','j','u','n','k',0}; 730 static const WCHAR shortcutW[] = {'A','l','t','+','t',0}; 731 732 IAccessible *acc; 733 IDispatch *disp; 734 IOleWindow *ow; 735 IEnumVARIANT *ev; 736 HWND chld, hwnd, hwnd2; 737 HRESULT hr; 738 VARIANT vid, v; 739 BSTR str; 740 POINT pt; 741 RECT rect; 742 LONG l, left, top, width, height; 743 ULONG fetched; 744 745 hwnd = CreateWindowA("oleacc_test", "test &t &junk", WS_OVERLAPPEDWINDOW, 746 0, 0, 100, 100, NULL, NULL, NULL, NULL); 747 ok(hwnd != NULL, "CreateWindow failed\n"); 748 chld = CreateWindowA("static", "message", WS_CHILD | WS_VISIBLE, 749 0, 0, 50, 50, hwnd, NULL, NULL, NULL); 750 ok(chld != NULL, "CreateWindow failed\n"); 751 752 hr = CreateStdAccessibleObject(NULL, OBJID_CLIENT, &IID_IAccessible, (void**)&acc); 753 ok(hr == E_FAIL, "got %x\n", hr); 754 755 hr = CreateStdAccessibleObject(hwnd, OBJID_CLIENT, &IID_IAccessible, (void**)&acc); 756 ok(hr == S_OK, "got %x\n", hr); 757 758 hr = IAccessible_QueryInterface(acc, &IID_IOleWindow, (void**)&ow); 759 ok(hr == S_OK, "got %x\n", hr); 760 hr = IOleWindow_GetWindow(ow, &hwnd2); 761 ok(hr == S_OK, "got %x\n", hr); 762 ok(hwnd == hwnd2, "hwnd2 = %p, expected %p\n", hwnd2, hwnd); 763 hr = WindowFromAccessibleObject(acc, &hwnd2); 764 ok(hr == S_OK, "got %x\n", hr); 765 ok(hwnd == hwnd2, "hwnd2 = %p, expected %p\n", hwnd2, hwnd); 766 IOleWindow_Release(ow); 767 768 hr = IAccessible_get_accChildCount(acc, &l); 769 ok(hr == S_OK, "got %x\n", hr); 770 ok(l == 1, "l = %d\n", l); 771 772 V_VT(&vid) = VT_I4; 773 V_I4(&vid) = CHILDID_SELF; 774 disp = (void*)0xdeadbeef; 775 hr = IAccessible_get_accChild(acc, vid, &disp); 776 ok(hr == E_INVALIDARG, "get_accChild returned %x\n", hr); 777 ok(disp == NULL, "disp = %p\n", disp); 778 779 V_I4(&vid) = 1; 780 disp = (void*)0xdeadbeef; 781 hr = IAccessible_get_accChild(acc, vid, &disp); 782 ok(hr == E_INVALIDARG, "get_accChild returned %x\n", hr); 783 ok(disp == NULL, "disp = %p\n", disp); 784 785 hr = IAccessible_QueryInterface(acc, &IID_IEnumVARIANT, (void**)&ev); 786 ok(hr == S_OK, "got %x\n", hr); 787 788 hr = IEnumVARIANT_Skip(ev, 100); 789 ok(hr == S_FALSE, "Skip returned %x\n", hr); 790 791 V_VT(&v) = VT_I4; 792 fetched = 1; 793 hr = IEnumVARIANT_Next(ev, 1, &v, &fetched); 794 ok(hr == S_FALSE, "got %x\n", hr); 795 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 796 ok(fetched == 0, "fetched = %d\n", fetched); 797 798 hr = IEnumVARIANT_Reset(ev); 799 ok(hr == S_OK, "got %x\n", hr); 800 801 V_VT(&v) = VT_I4; 802 fetched = 2; 803 hr = IEnumVARIANT_Next(ev, 1, &v, &fetched); 804 ok(hr == S_OK, "got %x\n", hr); 805 ok(V_VT(&v) == VT_DISPATCH, "V_VT(&v) = %d\n", V_VT(&v)); 806 IDispatch_Release(V_DISPATCH(&v)); 807 ok(fetched == 1, "fetched = %d\n", fetched); 808 IEnumVARIANT_Release(ev); 809 810 test_AccessibleChildren(acc); 811 812 V_VT(&vid) = VT_I4; 813 V_I4(&vid) = CHILDID_SELF; 814 hr = IAccessible_get_accName(acc, vid, &str); 815 ok(hr == S_OK, "got %x\n", hr); 816 ok(!lstrcmpW(str, testW), "name = %s\n", wine_dbgstr_w(str)); 817 SysFreeString(str); 818 819 V_I4(&vid) = 1; 820 str = (void*)0xdeadbeef; 821 hr = IAccessible_get_accName(acc, vid, &str); 822 ok(hr == E_INVALIDARG, "got %x\n", hr); 823 ok(!str, "str != NULL\n"); 824 V_I4(&vid) = CHILDID_SELF; 825 826 str = (void*)0xdeadbeef; 827 hr = IAccessible_get_accValue(acc, vid, &str); 828 ok(hr == S_FALSE, "got %x\n", hr); 829 ok(!str, "str != NULL\n"); 830 831 str = (void*)0xdeadbeef; 832 hr = IAccessible_get_accDescription(acc, vid, &str); 833 ok(hr == S_FALSE, "got %x\n", hr); 834 ok(!str, "str != NULL\n"); 835 836 V_VT(&v) = VT_DISPATCH; 837 V_DISPATCH(&v) = (void*)0xdeadbeef; 838 hr = IAccessible_get_accRole(acc, vid, &v); 839 ok(hr == S_OK, "got %x\n", hr); 840 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 841 ok(V_I4(&v) == ROLE_SYSTEM_CLIENT, "V_I4(&v) = %d\n", V_I4(&v)); 842 843 V_VT(&v) = VT_DISPATCH; 844 V_DISPATCH(&v) = (void*)0xdeadbeef; 845 hr = IAccessible_get_accState(acc, vid, &v); 846 ok(hr == S_OK, "got %x\n", hr); 847 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 848 ok(V_I4(&v) == (STATE_SYSTEM_FOCUSABLE|STATE_SYSTEM_INVISIBLE), 849 "V_I4(&v) = %x\n", V_I4(&v)); 850 851 str = (void*)0xdeadbeef; 852 hr = IAccessible_get_accHelp(acc, vid, &str); 853 ok(hr == S_FALSE, "got %x\n", hr); 854 ok(!str, "str != NULL\n"); 855 856 hr = IAccessible_get_accKeyboardShortcut(acc, vid, &str); 857 ok(hr == S_OK, "got %x\n", hr); 858 ok(!lstrcmpW(str, shortcutW), "str = %s\n", wine_dbgstr_w(str)); 859 SysFreeString(str); 860 861 str = (void*)0xdeadbeef; 862 hr = IAccessible_get_accDefaultAction(acc, vid, &str); 863 ok(hr == S_FALSE, "got %x\n", hr); 864 ok(!str, "str != NULL\n"); 865 866 pt.x = pt.y = 60; 867 ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n"); 868 hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v); 869 ok(hr == S_OK, "got %x\n", hr); 870 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 871 ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v)); 872 873 pt.x = pt.y = 25; 874 ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n"); 875 hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v); 876 ok(hr == S_OK, "got %x\n", hr); 877 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 878 ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v)); 879 880 ShowWindow(hwnd, TRUE); 881 pt.x = pt.y = 60; 882 ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n"); 883 hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v); 884 ok(hr == S_OK, "got %x\n", hr); 885 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 886 ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v)); 887 888 pt.x = pt.y = 25; 889 ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n"); 890 hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v); 891 ok(hr == S_OK, "got %x\n", hr); 892 ok(V_VT(&v) == VT_DISPATCH, "V_VT(&v) = %d\n", V_VT(&v)); 893 ok(V_DISPATCH(&v) != NULL, "V_DISPATCH(&v) = %p\n", V_DISPATCH(&v)); 894 VariantClear(&v); 895 896 ShowWindow(chld, FALSE); 897 pt.x = pt.y = 25; 898 ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n"); 899 hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v); 900 ok(hr == S_OK, "got %x\n", hr); 901 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 902 ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v)); 903 904 hr = IAccessible_get_accParent(acc, &disp); 905 ok(hr == S_OK, "got %x\n", hr); 906 ok(disp != NULL, "disp == NULL\n"); 907 IDispatch_Release(disp); 908 909 ok(GetClientRect(hwnd, &rect), "GetClientRect failed\n"); 910 pt.x = rect.left; 911 pt.y = rect.top; 912 MapWindowPoints(hwnd, NULL, &pt, 1); 913 rect.left = pt.x; 914 rect.top = pt.y; 915 pt.x = rect.right; 916 pt.y = rect.bottom; 917 MapWindowPoints(hwnd, NULL, &pt, 1); 918 hr = IAccessible_accLocation(acc, &left, &top, &width, &height, vid); 919 ok(hr == S_OK, "got %x\n", hr); 920 ok(left == rect.left, "left = %d, expected %d\n", left, rect.left); 921 ok(top == rect.top, "top = %d, expected %d\n", top, rect.top); 922 ok(width == pt.x-rect.left, "width = %d, expected %d\n", width, pt.x-rect.left); 923 ok(height == pt.y-rect.top, "height = %d, expected %d\n", height, pt.y-rect.top); 924 925 DestroyWindow(hwnd); 926 927 hr = IAccessible_get_accChildCount(acc, &l); 928 ok(hr == S_OK, "got %x\n", hr); 929 ok(l == 0, "l = %d\n", l); 930 931 hr = IAccessible_get_accName(acc, vid, &str); 932 ok(hr == E_INVALIDARG, "got %x\n", hr); 933 934 hr = IAccessible_get_accValue(acc, vid, &str); 935 ok(hr == S_FALSE, "got %x\n", hr); 936 937 hr = IAccessible_get_accRole(acc, vid, &v); 938 ok(hr == S_OK, "got %x\n", hr); 939 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 940 ok(V_I4(&v) == ROLE_SYSTEM_CLIENT, "V_I4(&v) = %d\n", V_I4(&v)); 941 942 hr = IAccessible_get_accState(acc, vid, &v); 943 ok(hr == S_OK, "got %x\n", hr); 944 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 945 ok(V_I4(&v) == STATE_SYSTEM_INVISIBLE, "V_I4(&v) = %x\n", V_I4(&v)); 946 947 hr = IAccessible_accHitTest(acc, 200, 200, &v); 948 ok(hr == S_OK, "got %x\n", hr); 949 ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v)); 950 ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v)); 951 952 disp = (void*)0xdeadbeef; 953 hr = IAccessible_get_accParent(acc, &disp); 954 ok(hr == E_FAIL, "got %x\n", hr); 955 ok(disp == NULL, "disp = %p\n", disp); 956 957 hr = IAccessible_accLocation(acc, &left, &top, &width, &height, vid); 958 ok(hr == S_OK, "got %x\n", hr); 959 ok(left == 0, "left = %d\n", left); 960 ok(top == 0, "top = %d\n", top); 961 ok(width == 0, "width = %d\n", width); 962 ok(height == 0, "height = %d\n", height); 963 964 IAccessible_Release(acc); 965 } 966 967 static void test_CAccPropServices(void) 968 { 969 IAccPropServices *acc_prop_services; 970 HRESULT hres; 971 972 hres = CoCreateInstance(&CLSID_CAccPropServices, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 973 &IID_IAccPropServices, (void**)&acc_prop_services); 974 ok(hres == S_OK, "Could not create CAccPropServices instance: %08x\n", hres); 975 976 IAccPropServices_Release(acc_prop_services); 977 } 978 979 START_TEST(main) 980 { 981 int argc; 982 char **argv; 983 984 if(!init()) 985 return; 986 987 CoInitializeEx(NULL, COINIT_MULTITHREADED); 988 989 argc = winetest_get_mainargs(&argv); 990 if(argc == 4 && !strcmp(argv[2], "ObjectFromLresult")) { 991 IUnknown *unk; 992 HRESULT hres; 993 LRESULT lres; 994 995 lres = _strtoi64( argv[3], NULL, 16 ); 996 hres = ObjectFromLresult(lres, &IID_IUnknown, 0, (void**)&unk); 997 ok(hres == S_OK, "hres = %x\n", hres); 998 IUnknown_Release(unk); 999 1000 CoUninitialize(); 1001 return; 1002 } 1003 1004 if(!register_window_class()) { 1005 skip("can't register test window class\n"); 1006 return; 1007 } 1008 1009 test_getroletext(); 1010 test_GetStateText(); 1011 test_LresultFromObject(argv[0]); 1012 test_AccessibleObjectFromWindow(); 1013 test_GetProcessHandleFromHwnd(); 1014 test_default_client_accessible_object(); 1015 test_AccessibleChildren(&Accessible); 1016 1017 unregister_window_class(); 1018 CoUninitialize(); 1019 1020 CoInitialize(NULL); 1021 test_CAccPropServices(); 1022 CoUninitialize(); 1023 } 1024