oleacc: Add AccessibleObjectFromWindow tests.
[wine/wine-gecko.git] / dlls / oleacc / tests / main.c
blobc5c50b8916adc961714e882a246c7df1fefff2ea
1 /*
2 * oleacc tests
4 * Copyright 2008 Nikolay Sivov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "wine/test.h"
24 #include <stdio.h>
26 #include "initguid.h"
27 #include <oleacc.h>
29 static void test_getroletext(void)
31 INT ret, role;
32 CHAR buf[2], *buff;
33 WCHAR bufW[2], *buffW;
35 /* wrong role number */
36 ret = GetRoleTextA(-1, NULL, 0);
37 ok(ret == 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret);
38 buf[0] = '*';
39 ret = GetRoleTextA(-1, buf, 2);
40 ok(ret == 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret);
41 ok(buf[0] == '*' ||
42 broken(buf[0] == 0), /* Win98 and WinMe */
43 "GetRoleTextA modified buffer on wrong role number\n");
44 buf[0] = '*';
45 ret = GetRoleTextA(-1, buf, 0);
46 ok(ret == 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret);
47 ok(buf[0] == '*', "GetRoleTextA modified buffer on wrong role number\n");
49 ret = GetRoleTextW(-1, NULL, 0);
50 ok(ret == 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret);
51 bufW[0] = '*';
52 ret = GetRoleTextW(-1, bufW, 2);
53 ok(ret == 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret);
54 ok(bufW[0] == '\0' ||
55 broken(bufW[0] == '*'), /* Win98 and WinMe */
56 "GetRoleTextW doesn't return NULL char on wrong role number\n");
57 bufW[0] = '*';
58 ret = GetRoleTextW(-1, bufW, 0);
59 ok(ret == 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret);
61 /* zero role number - not documented */
62 ret = GetRoleTextA(0, NULL, 0);
63 ok(ret > 0, "GetRoleTextA doesn't return (>0) for zero role number, got %d\n", ret);
64 ret = GetRoleTextW(0, NULL, 0);
65 ok(ret > 0, "GetRoleTextW doesn't return (>0) for zero role number, got %d\n", ret);
67 /* NULL buffer, return length */
68 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, NULL, 0);
69 ok(ret > 0, "GetRoleTextA doesn't return length on NULL buffer, got %d\n", ret);
70 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, NULL, 1);
71 ok(ret > 0, "GetRoleTextA doesn't return length on NULL buffer, got %d\n", ret);
72 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, NULL, 0);
73 ok(ret > 0, "GetRoleTextW doesn't return length on NULL buffer, got %d\n", ret);
74 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, NULL, 1);
75 ok(ret > 0, "GetRoleTextW doesn't return length on NULL buffer, got %d\n", ret);
77 /* use a smaller buffer */
78 buf[0] = '*';
79 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buf, 1);
80 ok(ret == 0, "GetRoleTextA returned wrong length\n");
81 ok(buf[0] == '\0', "GetRoleTextA returned not zero-length buffer\n");
82 buf[1] = '*';
83 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buf, 2);
84 ok(ret == 1 ||
85 ret == 0, /* Vista and W2K8 */
86 "GetRoleTextA returned wrong length, got %d, expected 0 or 1\n", ret);
87 if (ret == 1)
88 ok(buf[1] == '\0', "GetRoleTextA returned not zero-length buffer : (%c)\n", buf[1]);
90 bufW[0] = '*';
91 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, bufW, 1);
92 ok(ret == 0, "GetRoleTextW returned wrong length, got %d, expected 1\n", ret);
93 ok(bufW[0] == '\0', "GetRoleTextW returned not zero-length buffer\n");
94 bufW[1] = '*';
95 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, bufW, 2);
96 ok(ret == 1, "GetRoleTextW returned wrong length, got %d, expected 1\n", ret);
97 ok(bufW[1] == '\0', "GetRoleTextW returned not zero-length buffer\n");
99 /* use bigger buffer */
100 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, NULL, 0);
101 buff = HeapAlloc(GetProcessHeap(), 0, 2*ret);
102 buff[2*ret-1] = '*';
103 ret = GetRoleTextA(ROLE_SYSTEM_TITLEBAR, buff, 2*ret);
104 ok(buff[2*ret-1] == '*', "GetRoleTextA shouldn't modify this part of buffer\n");
105 HeapFree(GetProcessHeap(), 0, buff);
107 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, NULL, 0);
108 buffW = HeapAlloc(GetProcessHeap(), 0, 2*ret*sizeof(WCHAR));
109 buffW[2*ret-1] = '*';
110 ret = GetRoleTextW(ROLE_SYSTEM_TITLEBAR, buffW, 2*ret);
111 ok(buffW[2*ret-1] == '*', "GetRoleTextW shouldn't modify this part of buffer\n");
112 HeapFree(GetProcessHeap(), 0, buffW);
114 /* check returned length for all roles */
115 for(role = 0; role <= ROLE_SYSTEM_OUTLINEBUTTON; role++){
116 CHAR buff2[100];
117 WCHAR buff2W[100];
119 /* NT4 and W2K don't clear the buffer on a nonexistent role in the A-call */
120 memset(buff2, 0, sizeof(buff2));
122 ret = GetRoleTextA(role, NULL, 0);
123 /* Win98 up to W2K miss some of the roles */
124 if (role >= ROLE_SYSTEM_SPLITBUTTON)
125 ok(ret > 0 || broken(ret == 0), "Expected the role %d to be present\n", role);
126 else
127 ok(ret > 0, "Expected the role to be present\n");
129 GetRoleTextA(role, buff2, sizeof(buff2));
130 ok(ret == lstrlenA(buff2),
131 "GetRoleTextA: returned length doesn't match returned buffer for role %d\n", role);
133 /* Win98 and WinMe don't clear the buffer on a nonexistent role in the W-call */
134 memset(buff2W, 0, sizeof(buff2W));
136 ret = GetRoleTextW(role, NULL, 0);
137 GetRoleTextW(role, buff2W, sizeof(buff2W)/sizeof(WCHAR));
138 ok(ret == lstrlenW(buff2W),
139 "GetRoleTextW: returned length doesn't match returned buffer for role %d\n", role);
143 static int Object_ref = 1;
144 static HRESULT WINAPI Object_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
146 if(IsEqualIID(riid, &IID_IUnknown)) {
147 *ppv = iface;
148 IUnknown_AddRef(iface);
149 return S_OK;
151 return E_NOINTERFACE;
154 static ULONG WINAPI Object_AddRef(IUnknown *iface)
156 return InterlockedIncrement(&Object_ref);
159 static ULONG WINAPI Object_Release(IUnknown *iface)
161 return InterlockedDecrement(&Object_ref);
164 static IUnknownVtbl ObjectVtbl = {
165 Object_QueryInterface,
166 Object_AddRef,
167 Object_Release
170 static IUnknown Object = {&ObjectVtbl};
172 static void test_LresultFromObject(const char *name)
174 PROCESS_INFORMATION proc;
175 STARTUPINFOA startup;
176 char cmdline[MAX_PATH];
177 IUnknown *unk;
178 HRESULT hres;
179 LRESULT lres;
181 lres = LresultFromObject(NULL, 0, 0);
182 ok(lres == E_INVALIDARG, "got %lx\n", lres);
184 hres = ObjectFromLresult(0, &IID_IUnknown, 0, (void**)&unk);
185 ok(hres==MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,ERROR_INVALID_ADDRESS)
186 || hres==E_FAIL, "got %x\n", hres);
187 hres = ObjectFromLresult(0x10000, &IID_IUnknown, 0, (void**)&unk);
188 ok(hres==MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,ERROR_INVALID_ADDRESS)
189 || hres==E_FAIL, "got %x\n", hres);
191 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref);
192 lres = LresultFromObject(&IID_IUnknown, 0, &Object);
193 ok(SUCCEEDED(lres), "got %lx\n", lres);
194 ok(Object_ref > 1, "Object_ref = %d\n", Object_ref);
196 hres = ObjectFromLresult(lres, &IID_IUnknown, 0, (void**)&unk);
197 ok(hres == S_OK, "hres = %x\n", hres);
198 ok(unk == &Object, "unk != &Object\n");
199 IUnknown_Release(unk);
200 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref);
202 lres = LresultFromObject(&IID_IUnknown, 0, &Object);
203 ok(SUCCEEDED(lres), "got %lx\n", lres);
204 ok(Object_ref > 1, "Object_ref = %d\n", Object_ref);
206 sprintf(cmdline, "\"%s\" main ObjectFromLresult %lx", name, lres);
207 memset(&startup, 0, sizeof(startup));
208 startup.cb = sizeof(startup);
209 CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &proc);
210 winetest_wait_child_process(proc.hProcess);
211 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref);
214 static LRESULT WINAPI test_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
216 switch(msg) {
217 case WM_GETOBJECT:
218 ok(wparam==0xffffffff || broken(wparam==0x8000), "wparam = %lx\n", wparam);
219 if(lparam == (DWORD)OBJID_CURSOR)
220 return E_UNEXPECTED;
221 if(lparam == (DWORD)OBJID_CLIENT)
222 return LresultFromObject(&IID_IUnknown, wparam, &Object);
224 ok(0, "unexpected (%ld)\n", lparam);
225 return 0;
228 return DefWindowProcA(hwnd, msg, wparam, lparam);
231 static BOOL register_window_class(void)
233 WNDCLASSA cls;
235 memset(&cls, 0, sizeof(cls));
236 cls.lpfnWndProc = test_window_proc;
237 cls.lpszClassName = "oleacc_test";
238 cls.hInstance = GetModuleHandleA(NULL);
240 return RegisterClassA(&cls);
243 static void unregister_window_class(void)
245 UnregisterClassA("oleacc_test", NULL);
248 static void test_AccessibleObjectFromWindow(void)
250 IUnknown *unk;
251 HRESULT hr;
252 HWND hwnd;
254 hr = AccessibleObjectFromWindow(NULL, OBJID_CURSOR, &IID_IUnknown, NULL);
255 ok(hr == E_INVALIDARG, "got %x\n", hr);
257 hr = AccessibleObjectFromWindow(NULL, OBJID_CURSOR, &IID_IUnknown, (void**)&unk);
258 todo_wine ok(hr == S_OK, "got %x\n", hr);
259 if(hr == S_OK) IUnknown_Release(unk);
261 hwnd = CreateWindowA("oleacc_test", "test", WS_OVERLAPPEDWINDOW,
262 0, 0, 0, 0, NULL, NULL, NULL, NULL);
263 ok(hwnd != NULL, "CreateWindow failed\n");
265 hr = AccessibleObjectFromWindow(hwnd, OBJID_CURSOR, &IID_IUnknown, (void**)&unk);
266 ok(hr == E_UNEXPECTED, "got %x\n", hr);
268 ok(Object_ref == 1, "Object_ref = %d\n", Object_ref);
269 hr = AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, &IID_IUnknown, (void**)&unk);
270 ok(hr == S_OK, "got %x\n", hr);
271 ok(Object_ref == 2, "Object_ref = %d\n", Object_ref);
272 IUnknown_Release(unk);
274 DestroyWindow(hwnd);
277 START_TEST(main)
279 int argc;
280 char **argv;
282 CoInitializeEx(NULL, COINIT_MULTITHREADED);
284 argc = winetest_get_mainargs(&argv);
285 if(argc == 4 && !strcmp(argv[2], "ObjectFromLresult")) {
286 IUnknown *unk;
287 HRESULT hres;
288 LRESULT lres;
290 sscanf(argv[3], "%lx", &lres);
291 hres = ObjectFromLresult(lres, &IID_IUnknown, 0, (void**)&unk);
292 ok(hres == S_OK, "hres = %x\n", hres);
293 IUnknown_Release(unk);
295 CoUninitialize();
296 return;
299 if(!register_window_class()) {
300 skip("can't register test window class\n");
301 return;
304 test_getroletext();
305 test_LresultFromObject(argv[0]);
306 test_AccessibleObjectFromWindow();
308 unregister_window_class();
309 CoUninitialize();