Initialize COM for application-owned Wine accessibility objects
This commit is contained in:
1 parent
25e38907d3
commit
6976c83294
4 files changed
+84
-3
No files matched your search
+32
-1
@@ -1,13 +1,34 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#define COBJMACROS
|
||||
#include <windows.h>
|
||||
#include <initguid.h>
|
||||
#include <oleacc.h>
|
||||
|
||||
static HMENU bar, file, edit, nested, context;
|
||||
static int step;
|
||||
static HWND marshaledControl;
|
||||
static HWND button;
|
||||
|
||||
static LRESULT CALLBACK provider_proc(HWND window, UINT message, WPARAM wp, LPARAM lp) {
|
||||
if (message == WM_GETOBJECT && (LONG)lp == OBJID_CLIENT) {
|
||||
IAccessible *accessible = NULL;
|
||||
if (SUCCEEDED(CreateStdAccessibleObject(window, OBJID_CLIENT, &IID_IAccessible,
|
||||
(void **)&accessible))) {
|
||||
// Returning a marshaled object forces the separate helper to use COM,
|
||||
// rather than Wine's directly constructed native-control proxy.
|
||||
LRESULT result = LresultFromObject(&IID_IAccessible, wp, (IUnknown *)accessible);
|
||||
IAccessible_Release(accessible);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return DefWindowProcW(window, message, wp, lp);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK window_proc(HWND window, UINT message, WPARAM wp, LPARAM lp) {
|
||||
if (message == WM_TIMER) {
|
||||
switch (++step) {
|
||||
case 1:
|
||||
SetFocus(button);
|
||||
// Enter File through the application's actual native menu loop.
|
||||
PostMessageW(window, WM_SYSCOMMAND, SC_KEYMENU, 'f');
|
||||
break;
|
||||
@@ -73,6 +94,7 @@ static LRESULT CALLBACK window_proc(HWND window, UINT message, WPARAM wp, LPARAM
|
||||
|
||||
int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR args, int show) {
|
||||
(void)previous; (void)args; (void)show;
|
||||
if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) return 1;
|
||||
WNDCLASSW cls = {0};
|
||||
cls.hInstance = instance;
|
||||
cls.lpszClassName = L"WineAccessMenuFixture";
|
||||
@@ -92,15 +114,24 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR args, int show)
|
||||
HWND window = CreateWindowW(cls.lpszClassName, L"Wine menu fixture", WS_OVERLAPPEDWINDOW,
|
||||
120, 120, 400, 240, NULL, bar, instance, NULL);
|
||||
ShowWindow(window, SW_SHOW);
|
||||
HWND button = CreateWindowW(L"Button", L"Return to control", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
|
||||
button = CreateWindowW(L"Button", L"Return to control", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
|
||||
10, 10, 200, 30, window, NULL, instance, NULL);
|
||||
cls.lpszClassName = L"WineAccessMarshaledFixture";
|
||||
cls.lpfnWndProc = provider_proc;
|
||||
RegisterClassW(&cls);
|
||||
marshaledControl = CreateWindowW(cls.lpszClassName, L"Application-owned accessibility",
|
||||
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
|
||||
10, 60, 250, 30, window, NULL, instance, NULL);
|
||||
SetForegroundWindow(window);
|
||||
SetFocus(button);
|
||||
SetFocus(marshaledControl);
|
||||
NotifyWinEvent(EVENT_OBJECT_FOCUS, marshaledControl, OBJID_CLIENT, CHILDID_SELF);
|
||||
SetTimer(window, 1, 400, NULL);
|
||||
MSG message;
|
||||
while (GetMessageW(&message, NULL, 0, 0) > 0) {
|
||||
TranslateMessage(&message); DispatchMessageW(&message);
|
||||
}
|
||||
DestroyMenu(context);
|
||||
CoUninitialize();
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user