// SPDX-License-Identifier: LGPL-2.1-or-later #define UNICODE #define _UNICODE #include #include static HWND list, button; #ifdef WINE_ACCESS_DELPHI_FIXTURE static HWND okButton; #endif static int step; static LRESULT CALLBACK window_proc(HWND window, UINT message, WPARAM wp, LPARAM lp) { if (message == WM_TIMER) { switch (++step) { case 1: case 2: // Exercise keyboard processing, not synthetic accessibility events. SendMessageW(list, WM_KEYDOWN, VK_DOWN, 1); break; case 3: #ifdef WINE_ACCESS_DELPHI_FIXTURE SendMessageW(list, WM_KEYDOWN, VK_SPACE, 1); #else SendMessageW(list, WM_KEYDOWN, VK_UP, 1); #endif break; case 4: SetFocus(button); break; case 5: SetFocus(list); break; case 6: { #ifdef WINE_ACCESS_DELPHI_FIXTURE SendMessageW(list, WM_KEYDOWN, VK_SPACE, 1); #else LVITEMW item = {0}; item.pszText = L"Ready"; SendMessageW(list, LVM_SETITEMTEXTW, 0, (LPARAM)&item); NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, list, OBJID_CLIENT, CHILDID_SELF); #endif break; } case 7: SendMessageW(list, LVM_DELETEALLITEMS, 0, 0); break; #ifdef WINE_ACCESS_DELPHI_FIXTURE case 8: SetFocus(okButton); break; #endif default: DestroyWindow(window); } 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_LISTVIEW_CLASSES}; InitCommonControlsEx(&controls); WNDCLASSW cls = {0}; cls.hInstance = instance; cls.lpszClassName = L"WineAccessListFixture"; cls.lpfnWndProc = window_proc; RegisterClassW(&cls); HWND window = CreateWindowW(cls.lpszClassName, L"Wine list fixture", WS_OVERLAPPEDWINDOW, 120, 120, 600, 300, NULL, NULL, instance, NULL); #ifdef WINE_ACCESS_DELPHI_FIXTURE const WCHAR *nativeNames[] = {WC_LISTVIEWW, L"Button", L"Button", L"Static"}; const WCHAR *delphiNames[] = {L"TListView", L"TBitBtn", L"TButton", L"TStaticText"}; for (int i = 0; i < 4; ++i) { WNDCLASSEXW subclass = {0}; subclass.cbSize = sizeof(subclass); if (!GetClassInfoExW(NULL, nativeNames[i], &subclass)) return 1; subclass.hInstance = instance; subclass.lpszClassName = delphiNames[i]; if (!RegisterClassExW(&subclass)) return 2; } const WCHAR *buttonClass = L"TBitBtn", *listClass = L"TListView", *labelClass = L"TStaticText"; okButton = CreateWindowW(L"TButton", L"&OK", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 240, 240, 120, 30, window, NULL, instance, NULL); #else const WCHAR *buttonClass = L"Button", *listClass = WC_LISTVIEWW, *labelClass = L"Static"; #endif button = CreateWindowW(buttonClass, L"Return to control", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 10, 240, 200, 30, window, NULL, instance, NULL); CreateWindowW(labelClass, L"Required components", WS_CHILD | WS_VISIBLE, 10, 10, 550, 30, window, NULL, instance, NULL); list = CreateWindowW(listClass, L"List1", WS_CHILD | WS_VISIBLE | WS_TABSTOP | LVS_REPORT, 10, 50, 550, 180, window, NULL, instance, NULL); #ifdef WINE_ACCESS_DELPHI_FIXTURE SendMessageW(list, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); #endif LVCOLUMNW column = {0}; column.mask = LVCF_TEXT | LVCF_WIDTH; column.cx = 150; column.pszText = L"Status"; SendMessageW(list, LVM_INSERTCOLUMNW, 0, (LPARAM)&column); column.cx = 350; column.pszText = L"Component"; SendMessageW(list, LVM_INSERTCOLUMNW, 1, (LPARAM)&column); LVITEMW item = {0}; item.mask = LVIF_TEXT; item.pszText = L"Pending"; SendMessageW(list, LVM_INSERTITEMW, 0, (LPARAM)&item); item.iSubItem = 1; item.pszText = L"Runtime & tools β"; SendMessageW(list, LVM_SETITEMTEXTW, 0, (LPARAM)&item); item.iItem = 1; item.iSubItem = 0; item.pszText = L"Installed"; SendMessageW(list, LVM_INSERTITEMW, 0, (LPARAM)&item); item.iSubItem = 1; item.pszText = L"Second component"; SendMessageW(list, LVM_SETITEMTEXTW, 1, (LPARAM)&item); ShowWindow(window, SW_SHOW); SetForegroundWindow(window); // Match the installer: initially no row is selected or focused. SetFocus(list); SetTimer(window, 1, 500, NULL); MSG message; while (GetMessageW(&message, NULL, 0, 0) > 0) { TranslateMessage(&message); DispatchMessageW(&message); } return 0; }