More accessibility fixes using foobar2000 as a test.

This commit is contained in:
Storm Dragon committed 2026-10-10 15:30:23 -04:00
1 parent 22f50402c4
commit 5f78168c57
9 files changed
+407 -14

No files matched your search

+112
View File
@@ -0,0 +1,112 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <commctrl.h>
static HWND tabs, atlTabs, tree, combo, edit, button;
static HTREEITEM root;
static int step;
static void focus_control(HWND window) {
SetFocus(window);
NotifyWinEvent(EVENT_OBJECT_FOCUS, window, OBJID_CLIENT, CHILDID_SELF);
}
static LRESULT CALLBACK window_proc(HWND window, UINT message, WPARAM wp, LPARAM lp) {
if (message == WM_TIMER) {
switch (++step) {
case 1: SendMessageW(tabs, WM_KEYDOWN, VK_RIGHT, 1); break;
case 2: focus_control(button); break;
case 3: focus_control(atlTabs); break;
case 4: SendMessageW(atlTabs, WM_KEYDOWN, VK_RIGHT, 1); break;
case 5: focus_control(tree); break;
case 6: SendMessageW(tree, TVM_EXPAND, TVE_EXPAND, (LPARAM)root); break;
case 7: SendMessageW(tree, WM_KEYDOWN, VK_DOWN, 1); break;
case 8: focus_control(button); break;
case 9: focus_control(tree); break;
case 10: focus_control(combo); break;
case 11:
SendMessageW(combo, CB_SETCURSEL, 1, 0);
NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, combo, OBJID_CLIENT, CHILDID_SELF);
break;
case 12: focus_control(edit); break;
case 13: focus_control(atlTabs); break;
case 14: SendMessageW(atlTabs, TCM_DELETEALLITEMS, 0, 0); break;
case 15: focus_control(tree); break;
case 16: SendMessageW(tree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); break;
default: DestroyWindow(window); break;
}
return 0;
}
if (message == WM_DESTROY) { PostQuitMessage(0); return 0; }
return DefWindowProcW(window, message, wp, lp);
}
int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR args, int show) {
(void)previous; (void)args; (void)show;
INITCOMMONCONTROLSEX controls = {sizeof(controls), ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES};
InitCommonControlsEx(&controls);
WNDCLASSW cls = {0};
cls.hInstance = instance;
cls.lpszClassName = L"WineAccessControlsFixture";
cls.lpfnWndProc = window_proc;
RegisterClassW(&cls);
HWND window = CreateWindowW(cls.lpszClassName, L"Wine controls fixture", WS_OVERLAPPEDWINDOW,
120, 120, 700, 440, NULL, NULL, instance, NULL);
WNDCLASSEXW tabClass = {0};
tabClass.cbSize = sizeof(tabClass);
if (!GetClassInfoExW(NULL, WC_TABCONTROLW, &tabClass)) return 1;
tabClass.hInstance = instance;
tabClass.lpszClassName = L"ATL:SysTabControl32";
if (!RegisterClassExW(&tabClass)) return 2;
tabs = CreateWindowW(WC_TABCONTROLW, L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
10, 10, 300, 80, window, NULL, instance, NULL);
atlTabs = CreateWindowW(tabClass.lpszClassName, L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
330, 10, 300, 80, window, NULL, instance, NULL);
TCITEMW tab = {0};
tab.mask = TCIF_TEXT;
tab.pszText = L"Albums & artists β";
SendMessageW(tabs, TCM_INSERTITEMW, 0, (LPARAM)&tab);
tab.pszText = L"Details";
SendMessageW(tabs, TCM_INSERTITEMW, 1, (LPARAM)&tab);
tab.pszText = L"Default Playlist";
SendMessageW(atlTabs, TCM_INSERTITEMW, 0, (LPARAM)&tab);
tab.pszText = L"Second Playlist";
SendMessageW(atlTabs, TCM_INSERTITEMW, 1, (LPARAM)&tab);
tree = CreateWindowW(WC_TREEVIEWW, L"Tree1", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
10, 110, 300, 170, window, NULL, instance, NULL);
TVINSERTSTRUCTW node = {0};
node.hParent = TVI_ROOT;
node.hInsertAfter = TVI_LAST;
node.item.mask = TVIF_TEXT;
node.item.pszText = L"All music";
root = (HTREEITEM)SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&node);
node.hParent = root;
node.item.pszText = L"Artist & album β";
SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&node);
SendMessageW(tree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)root);
button = CreateWindowW(L"Button", L"Named native button", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
10, 310, 250, 30, window, NULL, instance, NULL);
combo = CreateWindowW(L"ComboBox", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST,
390, 110, 200, 150, window, NULL, instance, NULL);
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)L"by artist");
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)L"by year");
SendMessageW(combo, CB_SETCURSEL, 0, 0);
edit = CreateWindowW(L"Edit", L"search", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
390, 170, 200, 25, window, NULL, instance, NULL);
// Labels are deliberately created after their fields, like foobar2000.
CreateWindowW(L"Static", L"View:", WS_CHILD | WS_VISIBLE,
330, 110, 50, 25, window, NULL, instance, NULL);
CreateWindowW(L"Static", L"Filter:", WS_CHILD | WS_VISIBLE,
330, 170, 50, 25, window, NULL, instance, NULL);
ShowWindow(window, SW_SHOW);
SetForegroundWindow(window);
focus_control(tabs);
SetTimer(window, 1, 400, NULL);
MSG message;
while (GetMessageW(&message, NULL, 0, 0) > 0) {
TranslateMessage(&message); DispatchMessageW(&message);
}
return 0;
}