Read native Wine list-view rows in 32-bit and 64-bit applications

This commit is contained in:
Storm Dragon committed 2026-10-10 02:03:56 -04:00
1 parent 9aad6748e0
commit d7ea005a1f
8 files changed
+356 -4

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <commctrl.h>
static HWND list, button;
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:
SendMessageW(list, WM_KEYDOWN, VK_UP, 1);
break;
case 4: SetFocus(button); break;
case 5: SetFocus(list); break;
case 6: {
LVITEMW item = {0};
item.pszText = L"Ready";
SendMessageW(list, LVM_SETITEMTEXTW, 0, (LPARAM)&item);
NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, list, OBJID_CLIENT, CHILDID_SELF);
break;
}
case 7: SendMessageW(list, LVM_DELETEALLITEMS, 0, 0); break;
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);
button = CreateWindowW(L"Button", L"Return to control", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
10, 240, 200, 30, window, NULL, instance, NULL);
CreateWindowW(L"Static", L"Required components", WS_CHILD | WS_VISIBLE,
10, 10, 550, 30, window, NULL, instance, NULL);
list = CreateWindowW(WC_LISTVIEWW, L"List1", WS_CHILD | WS_VISIBLE | WS_TABSTOP | LVS_REPORT,
10, 50, 550, 180, window, NULL, instance, NULL);
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;
}