// SPDX-License-Identifier: LGPL-2.1-or-later #define UNICODE #define _UNICODE #include #include static HWND tabs, atlTabs, tree, combo, edit, button, list; 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); // Common file dialogs can change the selection without a WinEvent. 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; case 17: focus_control(list); 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"artist & album"); SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)L"year && date"); SendMessageW(combo, CB_SETCURSEL, 0, 0); edit = CreateWindowW(L"Edit", L"search & find", 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 && sort:", WS_CHILD | WS_VISIBLE, 330, 110, 50, 25, window, NULL, instance, NULL); CreateWindowW(L"Static", L"Filter & query:", WS_CHILD | WS_VISIBLE | SS_NOPREFIX, 330, 170, 50, 25, window, NULL, instance, NULL); list = CreateWindowW(L"ListBox", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 390, 220, 200, 80, window, NULL, instance, NULL); SendMessageW(list, LB_ADDSTRING, 0, (LPARAM)L"Rock & roll && blues"); SendMessageW(list, LB_SETCURSEL, 0, 0); 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; }