oleacc: Reorganize class specific behaviour handling.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9e133a9a22
commit
589be8c1be
|
@ -19,6 +19,7 @@
|
|||
#define COBJMACROS
|
||||
|
||||
#include "oleacc_private.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
|
@ -650,6 +651,38 @@ static const IEnumVARIANTVtbl ClientEnumVARIANTVtbl = {
|
|||
Client_EnumVARIANT_Clone
|
||||
};
|
||||
|
||||
static const struct win_class_data classes[] = {
|
||||
{WC_LISTBOXW, 0x10000, TRUE},
|
||||
{L"#32768", 0x10001, TRUE}, /* menu */
|
||||
{WC_BUTTONW, 0x10002, TRUE},
|
||||
{WC_STATICW, 0x10003, TRUE},
|
||||
{WC_EDITW, 0x10004, TRUE},
|
||||
{WC_COMBOBOXW, 0x10005, TRUE},
|
||||
{L"#32770", 0x10006, TRUE}, /* dialog */
|
||||
{L"#32771", 0x10007, TRUE}, /* winswitcher */
|
||||
{L"MDIClient", 0x10008, TRUE},
|
||||
{L"#32769", 0x10009, TRUE}, /* desktop */
|
||||
{WC_SCROLLBARW, 0x1000a, TRUE},
|
||||
{STATUSCLASSNAMEW, 0x1000b, TRUE},
|
||||
{TOOLBARCLASSNAMEW, 0x1000c, TRUE},
|
||||
{PROGRESS_CLASSW, 0x1000d, TRUE},
|
||||
{ANIMATE_CLASSW, 0x1000e, TRUE},
|
||||
{WC_TABCONTROLW, 0x1000f, TRUE},
|
||||
{HOTKEY_CLASSW, 0x10010, TRUE},
|
||||
{WC_HEADERW, 0x10011, TRUE},
|
||||
{TRACKBAR_CLASSW, 0x10012, TRUE},
|
||||
{WC_LISTVIEWW, 0x10013, TRUE},
|
||||
{UPDOWN_CLASSW, 0x10016, TRUE},
|
||||
{TOOLTIPS_CLASSW, 0x10018, TRUE},
|
||||
{WC_TREEVIEWW, 0x10019, TRUE},
|
||||
{DATETIMEPICK_CLASSW, 0, TRUE},
|
||||
{WC_IPADDRESSW, 0, TRUE},
|
||||
{L"RICHEDIT", 0x1001c, TRUE},
|
||||
{L"RichEdit20A", 0, TRUE},
|
||||
{L"RichEdit20W", 0, TRUE},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj)
|
||||
{
|
||||
Client *client;
|
||||
|
@ -662,6 +695,8 @@ HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj)
|
|||
if(!client)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
find_class_data(hwnd, classes);
|
||||
|
||||
client->IAccessible_iface.lpVtbl = &ClientVtbl;
|
||||
client->IOleWindow_iface.lpVtbl = &ClientOleWindowVtbl;
|
||||
client->IEnumVARIANT_iface.lpVtbl = &ClientEnumVARIANTVtbl;
|
||||
|
|
|
@ -20,13 +20,6 @@
|
|||
|
||||
#define COBJMACROS
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "ole2.h"
|
||||
#include "commctrl.h"
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "initguid.h"
|
||||
#include "oleacc_private.h"
|
||||
#include "resource.h"
|
||||
|
@ -37,50 +30,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(oleacc);
|
|||
|
||||
static const WCHAR lresult_atom_prefix[] = {'w','i','n','e','_','o','l','e','a','c','c',':'};
|
||||
|
||||
typedef HRESULT (*accessible_create)(HWND, const IID*, void**);
|
||||
|
||||
extern HRESULT WINAPI OLEACC_DllGetClassObject(REFCLSID, REFIID, void**) DECLSPEC_HIDDEN;
|
||||
extern BOOL WINAPI OLEACC_DllMain(HINSTANCE, DWORD, void*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI OLEACC_DllRegisterServer(void) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI OLEACC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
|
||||
|
||||
static struct {
|
||||
const WCHAR *name;
|
||||
DWORD idx;
|
||||
accessible_create create_client;
|
||||
accessible_create create_window;
|
||||
} builtin_classes[] = {
|
||||
{WC_LISTBOXW, 0x10000, NULL, NULL},
|
||||
{L"#32768", 0x10001, NULL, NULL}, /* menu */
|
||||
{WC_BUTTONW, 0x10002, NULL, NULL},
|
||||
{WC_STATICW, 0x10003, NULL, NULL},
|
||||
{WC_EDITW, 0x10004, NULL, NULL},
|
||||
{WC_COMBOBOXW, 0x10005, NULL, NULL},
|
||||
{L"#32770", 0x10006, NULL, NULL}, /* dialog */
|
||||
{L"#32771", 0x10007, NULL, NULL}, /* winswitcher */
|
||||
{L"MDIClient", 0x10008, NULL, NULL},
|
||||
{L"#32769", 0x10009, NULL, NULL}, /* desktop */
|
||||
{WC_SCROLLBARW, 0x1000a, NULL, NULL},
|
||||
{STATUSCLASSNAMEW, 0x1000b, NULL, NULL},
|
||||
{TOOLBARCLASSNAMEW, 0x1000c, NULL, NULL},
|
||||
{PROGRESS_CLASSW, 0x1000d, NULL, NULL},
|
||||
{ANIMATE_CLASSW, 0x1000e, NULL, NULL},
|
||||
{WC_TABCONTROLW, 0x1000f, NULL, NULL},
|
||||
{HOTKEY_CLASSW, 0x10010, NULL, NULL},
|
||||
{WC_HEADERW, 0x10011, NULL, NULL},
|
||||
{TRACKBAR_CLASSW, 0x10012, NULL, NULL},
|
||||
{WC_LISTVIEWW, 0x10013, NULL, NULL},
|
||||
{UPDOWN_CLASSW, 0x10016, NULL, NULL},
|
||||
{TOOLTIPS_CLASSW, 0x10018, NULL, NULL},
|
||||
{WC_TREEVIEWW, 0x10019, NULL, NULL},
|
||||
{MONTHCAL_CLASSW, 0, NULL, NULL},
|
||||
{DATETIMEPICK_CLASSW, 0, NULL, NULL},
|
||||
{WC_IPADDRESSW, 0, NULL, NULL},
|
||||
{L"RICHEDIT", 0x1001c, NULL, NULL},
|
||||
{L"RichEdit20A", 0, NULL, NULL},
|
||||
{L"RichEdit20W", 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static HINSTANCE oleacc_handle = 0;
|
||||
|
||||
int convert_child_id(VARIANT *v)
|
||||
|
@ -94,7 +48,7 @@ int convert_child_id(VARIANT *v)
|
|||
}
|
||||
}
|
||||
|
||||
static accessible_create get_builtin_accessible_obj(HWND hwnd, LONG objid)
|
||||
const struct win_class_data* find_class_data(HWND hwnd, const struct win_class_data *classes)
|
||||
{
|
||||
WCHAR class_name[64];
|
||||
int i, idx;
|
||||
|
@ -103,31 +57,21 @@ static accessible_create get_builtin_accessible_obj(HWND hwnd, LONG objid)
|
|||
return NULL;
|
||||
TRACE("got window class: %s\n", debugstr_w(class_name));
|
||||
|
||||
for(i=0; i<ARRAY_SIZE(builtin_classes); i++) {
|
||||
if(!wcsicmp(class_name, builtin_classes[i].name)) {
|
||||
accessible_create ret;
|
||||
|
||||
ret = (objid==OBJID_CLIENT ?
|
||||
builtin_classes[i].create_client :
|
||||
builtin_classes[i].create_window);
|
||||
if(!ret)
|
||||
for(i=0; classes[i].name; i++) {
|
||||
if(!wcsicmp(class_name, classes[i].name)) {
|
||||
if(classes[i].stub)
|
||||
FIXME("unhandled window class: %s\n", debugstr_w(class_name));
|
||||
return ret;
|
||||
return &classes[i];
|
||||
}
|
||||
}
|
||||
|
||||
idx = SendMessageW(hwnd, WM_GETOBJECT, 0, OBJID_QUERYCLASSNAMEIDX);
|
||||
if(idx) {
|
||||
for(i=0; i<ARRAY_SIZE(builtin_classes); i++) {
|
||||
if(idx == builtin_classes[i].idx) {
|
||||
accessible_create ret;
|
||||
|
||||
ret = (objid==OBJID_CLIENT ?
|
||||
builtin_classes[i].create_client :
|
||||
builtin_classes[i].create_window);
|
||||
if(!ret)
|
||||
FIXME("unhandled class name idx: %x\n", idx);
|
||||
return ret;
|
||||
for(i=0; classes[i].name; i++) {
|
||||
if(idx == classes[i].idx) {
|
||||
if(classes[i].stub)
|
||||
FIXME("unhandled window class: %s\n", debugstr_w(class_name));
|
||||
return &classes[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,19 +84,13 @@ static accessible_create get_builtin_accessible_obj(HWND hwnd, LONG objid)
|
|||
HRESULT WINAPI CreateStdAccessibleObject( HWND hwnd, LONG idObject,
|
||||
REFIID riidInterface, void** ppvObject )
|
||||
{
|
||||
accessible_create create;
|
||||
|
||||
TRACE("%p %d %s %p\n", hwnd, idObject,
|
||||
debugstr_guid( riidInterface ), ppvObject );
|
||||
|
||||
switch(idObject) {
|
||||
case OBJID_CLIENT:
|
||||
create = get_builtin_accessible_obj(hwnd, idObject);
|
||||
if(create) return create(hwnd, riidInterface, ppvObject);
|
||||
return create_client_object(hwnd, riidInterface, ppvObject);
|
||||
case OBJID_WINDOW:
|
||||
create = get_builtin_accessible_obj(hwnd, idObject);
|
||||
if(create) return create(hwnd, riidInterface, ppvObject);
|
||||
return create_window_object(hwnd, riidInterface, ppvObject);
|
||||
default:
|
||||
FIXME("unhandled object id: %d\n", idObject);
|
||||
|
|
|
@ -18,6 +18,13 @@
|
|||
|
||||
#include "oleacc_classes.h"
|
||||
|
||||
struct win_class_data {
|
||||
const WCHAR *name;
|
||||
DWORD idx;
|
||||
BOOL stub;
|
||||
};
|
||||
const struct win_class_data* find_class_data(HWND, const struct win_class_data*) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT create_client_object(HWND, const IID*, void**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_window_object(HWND, const IID*, void**) DECLSPEC_HIDDEN;
|
||||
HRESULT get_accpropservices_factory(REFIID, void**) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "initguid.h"
|
||||
#include <ole2.h>
|
||||
#include <commctrl.h>
|
||||
#include <oleacc.h>
|
||||
|
||||
#define DEFINE_EXPECT(func) \
|
||||
|
@ -50,6 +52,7 @@
|
|||
expect_ ## func = called_ ## func = FALSE; \
|
||||
}while(0)
|
||||
|
||||
DEFINE_EXPECT(winproc_GETOBJECT);
|
||||
DEFINE_EXPECT(Accessible_QI_IEnumVARIANT);
|
||||
DEFINE_EXPECT(Accessible_get_accChildCount);
|
||||
DEFINE_EXPECT(Accessible_get_accChild);
|
||||
|
@ -1313,6 +1316,87 @@ static void test_CAccPropServices(void)
|
|||
IAccPropServices_Release(acc_prop_services);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI test_query_class(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (msg != WM_GETOBJECT)
|
||||
return 0;
|
||||
|
||||
CHECK_EXPECT(winproc_GETOBJECT);
|
||||
ok(!wparam, "wparam = %lx\n", wparam);
|
||||
ok(lparam == OBJID_QUERYCLASSNAMEIDX, "lparam = %lx\n", lparam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_CreateStdAccessibleObject_classes(void)
|
||||
{
|
||||
static const struct {
|
||||
const WCHAR *class;
|
||||
BOOL window; /* uses default window accessibility object */
|
||||
BOOL client; /* uses default client accessibility object */
|
||||
} tests[] =
|
||||
{
|
||||
{ WC_LISTBOXW },
|
||||
{ L"#32768" },
|
||||
{ WC_BUTTONW, TRUE },
|
||||
{ WC_STATICW, TRUE },
|
||||
{ WC_EDITW, TRUE },
|
||||
{ WC_COMBOBOXW, TRUE },
|
||||
{ L"#32770", TRUE },
|
||||
{ L"#32769", TRUE },
|
||||
{ WC_SCROLLBARW, TRUE },
|
||||
{ STATUSCLASSNAMEW, TRUE },
|
||||
{ TOOLBARCLASSNAMEW, TRUE },
|
||||
{ PROGRESS_CLASSW, TRUE },
|
||||
{ ANIMATE_CLASSW, TRUE },
|
||||
{ WC_TABCONTROLW, TRUE },
|
||||
{ HOTKEY_CLASSW, TRUE },
|
||||
{ WC_HEADERW, TRUE },
|
||||
{ TRACKBAR_CLASSW, TRUE },
|
||||
{ WC_LISTVIEWW, TRUE },
|
||||
{ UPDOWN_CLASSW, TRUE },
|
||||
{ TOOLTIPS_CLASSW, TRUE },
|
||||
{ WC_TREEVIEWW, TRUE },
|
||||
{ MONTHCAL_CLASSW, TRUE, TRUE },
|
||||
{ DATETIMEPICK_CLASSW, TRUE },
|
||||
{ WC_IPADDRESSW, TRUE }
|
||||
};
|
||||
|
||||
LRESULT (WINAPI *win_proc)(HWND, UINT, WPARAM, LPARAM);
|
||||
IAccessible *acc;
|
||||
HRESULT hr;
|
||||
HWND hwnd;
|
||||
int i;
|
||||
|
||||
for(i=0; i<ARRAY_SIZE(tests); i++)
|
||||
{
|
||||
winetest_push_context("class = %s", wine_dbgstr_w(tests[i].class));
|
||||
hwnd = CreateWindowW(tests[i].class, L"name", WS_OVERLAPPEDWINDOW,
|
||||
0, 0, 0, 0, NULL, NULL, NULL, NULL);
|
||||
ok(hwnd != NULL, "CreateWindow failed\n");
|
||||
win_proc = (void*)SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)test_query_class);
|
||||
|
||||
if (tests[i].client)
|
||||
SET_EXPECT(winproc_GETOBJECT);
|
||||
hr = CreateStdAccessibleObject(hwnd, OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
|
||||
ok(hr == S_OK, "CreateStdAccessibleObject failed %x\n", hr);
|
||||
if (tests[i].client)
|
||||
CHECK_CALLED(winproc_GETOBJECT);
|
||||
IAccessible_Release(acc);
|
||||
|
||||
if (tests[i].window)
|
||||
SET_EXPECT(winproc_GETOBJECT);
|
||||
hr = CreateStdAccessibleObject(hwnd, OBJID_WINDOW, &IID_IAccessible, (void**)&acc);
|
||||
ok(hr == S_OK, "CreateStdAccessibleObject failed %x\n", hr);
|
||||
if (tests[i].window)
|
||||
CHECK_CALLED(winproc_GETOBJECT);
|
||||
IAccessible_Release(acc);
|
||||
|
||||
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)win_proc);
|
||||
CloseWindow(hwnd);
|
||||
winetest_pop_context();
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(main)
|
||||
{
|
||||
int argc;
|
||||
|
@ -1351,6 +1435,7 @@ START_TEST(main)
|
|||
test_default_client_accessible_object();
|
||||
test_AccessibleChildren(&Accessible);
|
||||
test_AccessibleObjectFromEvent();
|
||||
test_CreateStdAccessibleObject_classes();
|
||||
|
||||
unregister_window_class();
|
||||
CoUninitialize();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define COBJMACROS
|
||||
|
||||
#include "oleacc_private.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
|
@ -416,6 +417,12 @@ static const IEnumVARIANTVtbl WindowEnumVARIANTVtbl = {
|
|||
Window_EnumVARIANT_Clone
|
||||
};
|
||||
|
||||
static const struct win_class_data classes[] = {
|
||||
{WC_LISTBOXW, 0x10000, TRUE},
|
||||
{L"#32768", 0x10001, TRUE}, /* menu */
|
||||
{NULL}
|
||||
};
|
||||
|
||||
HRESULT create_window_object(HWND hwnd, const IID *iid, void **obj)
|
||||
{
|
||||
Window *window;
|
||||
|
@ -428,6 +435,8 @@ HRESULT create_window_object(HWND hwnd, const IID *iid, void **obj)
|
|||
if(!window)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
find_class_data(hwnd, classes);
|
||||
|
||||
window->IAccessible_iface.lpVtbl = &WindowVtbl;
|
||||
window->IOleWindow_iface.lpVtbl = &WindowOleWindowVtbl;
|
||||
window->IEnumVARIANT_iface.lpVtbl = &WindowEnumVARIANTVtbl;
|
||||
|
|
Loading…
Reference in New Issue