103 lines
4.1 KiB
C
103 lines
4.1 KiB
C
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
// Drive a disposable copy of GoldWave 5.70 using real Wine keyboard input.
|
|
#include <windows.h>
|
|
#include <dlgs.h>
|
|
|
|
static DWORD appPid;
|
|
static HWND app, dialog;
|
|
|
|
static BOOL CALLBACK dismiss_setup(HWND window, LPARAM unused) {
|
|
(void)unused;
|
|
WCHAR text[64] = {0};
|
|
GetWindowTextW(window, text, 64);
|
|
if (!lstrcmpW(text, L"No") || !lstrcmpW(text, L"&No"))
|
|
PostMessageW(window, BM_CLICK, 0, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL CALLBACK find_window(HWND window, LPARAM unused) {
|
|
(void)unused;
|
|
DWORD pid = 0;
|
|
WCHAR title[128] = {0};
|
|
GetWindowThreadProcessId(window, &pid);
|
|
GetWindowTextW(window, title, 128);
|
|
if (pid == appPid && IsWindowVisible(window)) {
|
|
WCHAR cls[128] = {0};
|
|
GetClassNameW(window, cls, 128);
|
|
if (!lstrcmpW(cls, L"TGWMainForm")) app = window;
|
|
if (GetDlgItem(window, cmb1)) dialog = window;
|
|
if (!lstrcmpW(cls, L"TMessageForm")) EnumChildWindows(window, dismiss_setup, 0);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void key(WORD vk, BOOL alt, BOOL control) {
|
|
INPUT input[6] = {0};
|
|
UINT count = 0;
|
|
if (alt) { input[count].ki.wVk = VK_MENU; ++count; }
|
|
if (control) { input[count].ki.wVk = VK_CONTROL; ++count; }
|
|
input[count++].ki.wVk = vk;
|
|
input[count].ki.wVk = vk; input[count++].ki.dwFlags = KEYEVENTF_KEYUP;
|
|
if (control) { input[count].ki.wVk = VK_CONTROL; input[count++].ki.dwFlags = KEYEVENTF_KEYUP; }
|
|
if (alt) { input[count].ki.wVk = VK_MENU; input[count++].ki.dwFlags = KEYEVENTF_KEYUP; }
|
|
for (UINT i = 0; i < count; ++i) input[i].type = INPUT_KEYBOARD;
|
|
if (SendInput(count, input, sizeof(INPUT)) != count) ExitProcess(3);
|
|
Sleep(400);
|
|
}
|
|
|
|
int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR args, int show) {
|
|
(void)instance; (void)previous; (void)args; (void)show;
|
|
// The runner supplies a fresh prefix; this setting never touches the user's
|
|
// configuration. Match the reported Force screen reader mode setup.
|
|
HKEY options;
|
|
if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\GoldWave\\GoldWave\\Options", 0,
|
|
NULL, 0, KEY_SET_VALUE, NULL, &options, NULL) != ERROR_SUCCESS) return 2;
|
|
DWORD startupOptions = 0x3008;
|
|
RegSetValueExW(options, L"StartupOptions", 0, REG_DWORD, (BYTE *)&startupOptions, sizeof(startupOptions));
|
|
RegCloseKey(options);
|
|
if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\GoldWave\\GoldWave", 0,
|
|
NULL, 0, KEY_SET_VALUE, NULL, &options, NULL) != ERROR_SUCCESS) return 2;
|
|
const WCHAR version[] = L"5.70";
|
|
RegSetValueExW(options, L"Version", 0, REG_SZ, (const BYTE *)version, sizeof(version));
|
|
RegCloseKey(options);
|
|
WCHAR executable[4096] = {0};
|
|
if (!GetEnvironmentVariableW(L"WINE_ACCESS_GOLDWAVE_EXE", executable, 4096)) return 2;
|
|
STARTUPINFOW startup = {0};
|
|
startup.cb = sizeof(startup);
|
|
PROCESS_INFORMATION process = {0};
|
|
if (!CreateProcessW(executable, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &process)) return 2;
|
|
appPid = process.dwProcessId;
|
|
for (int i = 0; i < 200 && !app; ++i) { EnumWindows(find_window, 0); Sleep(50); }
|
|
if (!app) return 2;
|
|
SetForegroundWindow(app);
|
|
Sleep(500);
|
|
key('F', TRUE, FALSE);
|
|
key(VK_DOWN, FALSE, FALSE);
|
|
key(VK_DOWN, FALSE, FALSE);
|
|
key(VK_ESCAPE, FALSE, FALSE);
|
|
key(VK_ESCAPE, FALSE, FALSE);
|
|
key('O', FALSE, TRUE);
|
|
for (int i = 0; i < 100 && !dialog; ++i) { EnumWindows(find_window, 0); Sleep(50); }
|
|
if (!dialog) return 2;
|
|
HWND combo = GetDlgItem(dialog, cmb1);
|
|
SendMessageW(dialog, WM_NEXTDLGCTL, (WPARAM)combo, TRUE);
|
|
Sleep(500);
|
|
WCHAR before[512] = {0}, after[512] = {0};
|
|
SendMessageW(combo, WM_GETTEXT, 512, (LPARAM)before);
|
|
key(VK_DOWN, FALSE, FALSE);
|
|
SendMessageW(combo, WM_GETTEXT, 512, (LPARAM)after);
|
|
if (!lstrcmpW(before, after)) return 4;
|
|
GUITHREADINFO info = {0};
|
|
info.cbSize = sizeof(info);
|
|
GetGUIThreadInfo(GetWindowThreadProcessId(dialog, NULL), &info);
|
|
if (info.hwndFocus != combo) return 4;
|
|
key(VK_DOWN, FALSE, FALSE);
|
|
key(VK_UP, FALSE, FALSE);
|
|
key(VK_ESCAPE, FALSE, FALSE);
|
|
PostMessageW(app, WM_CLOSE, 0, 0);
|
|
int result = WaitForSingleObject(process.hProcess, 3000) == WAIT_OBJECT_0 ? 0 : 2;
|
|
CloseHandle(process.hThread);
|
|
CloseHandle(process.hProcess);
|
|
return result;
|
|
}
|