mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
Merge branch 'radiobutton' into 'master'
comctl32 & user32: Mark radio buttons at selected when focused See merge request wine/wine!5759
This commit is contained in:
commit
b689d130cc
4 changed files with 223 additions and 2 deletions
|
@ -628,15 +628,18 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
infoPtr->state |= BUTTON_BTNPRESSED;
|
||||||
SetFocus( hWnd );
|
SetFocus( hWnd );
|
||||||
|
|
||||||
if ((btn_type == BS_SPLITBUTTON || btn_type == BS_DEFSPLITBUTTON) &&
|
if ((btn_type == BS_SPLITBUTTON || btn_type == BS_DEFSPLITBUTTON) &&
|
||||||
!(infoPtr->split_style & BCSS_NOSPLIT) &&
|
!(infoPtr->split_style & BCSS_NOSPLIT) &&
|
||||||
notify_split_button_dropdown(infoPtr, &pt, hWnd))
|
notify_split_button_dropdown(infoPtr, &pt, hWnd))
|
||||||
|
{
|
||||||
|
infoPtr->state &= ~BUTTON_BTNPRESSED;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SetCapture( hWnd );
|
SetCapture( hWnd );
|
||||||
infoPtr->state |= BUTTON_BTNPRESSED;
|
|
||||||
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -867,6 +870,12 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
||||||
|
|
||||||
if (style & BS_NOTIFY)
|
if (style & BS_NOTIFY)
|
||||||
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
|
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
|
||||||
|
|
||||||
|
if (((btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON)) &&
|
||||||
|
!(infoPtr->state & (BST_CHECKED | BUTTON_BTNPRESSED)))
|
||||||
|
{
|
||||||
|
BUTTON_NOTIFY_PARENT(hWnd, BN_CLICKED);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
|
|
|
@ -2462,6 +2462,113 @@ static void test_getobject(void)
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_radiobutton_focus(void)
|
||||||
|
{
|
||||||
|
HWND hwnd, button;
|
||||||
|
MSG msg;
|
||||||
|
int i;
|
||||||
|
DWORD types[] = { BS_RADIOBUTTON, BS_AUTORADIOBUTTON };
|
||||||
|
|
||||||
|
static const struct message set_focus_default_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_SETFOCUS, sent },
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) },
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_BUTTON, BN_CLICKED) },
|
||||||
|
{ WM_PAINT, sent },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message set_focus_checked_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_SETFOCUS, sent },
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) },
|
||||||
|
{ WM_PAINT, sent },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message WM_LBUTTONDOWN_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
|
||||||
|
{ WM_KILLFOCUS, sent|parent },
|
||||||
|
{ WM_IME_SETCONTEXT, sent|optional|parent },
|
||||||
|
{ WM_IME_SETCONTEXT, sent|optional|defwinproc },
|
||||||
|
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
|
||||||
|
{ WM_SETFOCUS, sent|defwinproc },
|
||||||
|
{ WM_COMMAND, sent|parent },
|
||||||
|
{ BM_SETSTATE, sent|wparam|defwinproc, TRUE },
|
||||||
|
{ EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
|
||||||
|
{ WM_PAINT, sent },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message set_focus_without_notify_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_SETFOCUS, sent },
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, ID_BUTTON },
|
||||||
|
{ WM_PAINT, sent },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
hwnd = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
|
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||||
|
ok(hwnd != 0, "Failed to create parent window\n");
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(types); i++)
|
||||||
|
{
|
||||||
|
/* Test default button */
|
||||||
|
button = create_button(types[i] | WS_VISIBLE, hwnd);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
ok_sequence(sequences, COMBINED_SEQ_INDEX, set_focus_default_seq, "WM_SETFOCUS on default radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test already checked button */
|
||||||
|
button = create_button(types[i] | WS_VISIBLE, hwnd);
|
||||||
|
SendMessageA(button, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
ok_sequence(sequences, COMBINED_SEQ_INDEX, set_focus_checked_seq, "WM_SETFOCUS on checked radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test already focused button */
|
||||||
|
button = create_button(types[i] | WS_VISIBLE, hwnd);
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
SendMessageA(button, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
ok_sequence(sequences, COMBINED_SEQ_INDEX, set_focus_default_seq, "WM_SETFOCUS on focused radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test WM_LBUTTONDOWN */
|
||||||
|
button = create_button(types[i] | WS_VISIBLE, hwnd);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
SendMessageA(button, WM_LBUTTONDOWN, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
ok_sequence(sequences, COMBINED_SEQ_INDEX, WM_LBUTTONDOWN_seq, "WM_LBUTTONDOWN on radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test without BS_NOTIFY */
|
||||||
|
button = CreateWindowExA(0, WC_BUTTONA, "test", types[i] | WS_VISIBLE | WS_CHILD, 0, 0, 50, 14, hwnd, (HMENU)ID_BUTTON, 0, NULL);
|
||||||
|
ok(hwnd != NULL, "failed to create a button, 0x%08lx, %p\n", types[i] | WS_VISIBLE | WS_CHILD, hwnd);
|
||||||
|
pSetWindowSubclass(button, button_subclass_proc, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
ok_sequence(sequences, COMBINED_SEQ_INDEX, set_focus_without_notify_seq, "WM_SETFOCUS on radiobutton withouth BS_NOTIFY", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(button)
|
START_TEST(button)
|
||||||
{
|
{
|
||||||
BOOL (WINAPI * pIsThemeActive)(VOID);
|
BOOL (WINAPI * pIsThemeActive)(VOID);
|
||||||
|
@ -2500,6 +2607,7 @@ START_TEST(button)
|
||||||
test_style();
|
test_style();
|
||||||
test_visual();
|
test_visual();
|
||||||
test_getobject();
|
test_getobject();
|
||||||
|
test_radiobutton_focus();
|
||||||
|
|
||||||
uninit_winevent_hook();
|
uninit_winevent_hook();
|
||||||
|
|
||||||
|
|
|
@ -257,8 +257,8 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
NtUserSetCapture( hWnd );
|
NtUserSetCapture( hWnd );
|
||||||
NtUserSetFocus( hWnd );
|
|
||||||
set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
|
set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
|
||||||
|
NtUserSetFocus( hWnd );
|
||||||
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -381,6 +381,12 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
|
||||||
paint_button( hWnd, btn_type, ODA_FOCUS );
|
paint_button( hWnd, btn_type, ODA_FOCUS );
|
||||||
if (style & BS_NOTIFY)
|
if (style & BS_NOTIFY)
|
||||||
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
|
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
|
||||||
|
|
||||||
|
if (((btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON)) &&
|
||||||
|
!(get_button_state(hWnd) & (BST_CHECKED | BUTTON_BTNPRESSED)))
|
||||||
|
{
|
||||||
|
BUTTON_NOTIFY_PARENT(hWnd, BN_CLICKED);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
|
|
|
@ -20538,6 +20538,103 @@ static void test_hook_changing_window_proc(void)
|
||||||
DestroyWindow( hwnd );
|
DestroyWindow( hwnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_radiobutton_focus(void)
|
||||||
|
{
|
||||||
|
HWND hwnd, button;
|
||||||
|
DWORD style;
|
||||||
|
MSG msg;
|
||||||
|
int i;
|
||||||
|
DWORD types[] = { BS_RADIOBUTTON, BS_AUTORADIOBUTTON };
|
||||||
|
|
||||||
|
static const struct message set_focus_default_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) },
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_BUTTON, BN_CLICKED) },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message set_focus_checked_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message WM_LBUTTONDOWN_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_KILLFOCUS, sent|parent },
|
||||||
|
{ WM_IME_SETCONTEXT, sent|optional|parent },
|
||||||
|
{ WM_IME_SETCONTEXT, sent|optional|defwinproc },
|
||||||
|
{ WM_COMMAND, sent|parent },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message set_focus_without_notify_seq[] =
|
||||||
|
{
|
||||||
|
{ WM_COMMAND, sent|parent|wparam, ID_BUTTON },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
hwnd = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
|
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||||
|
ok(hwnd != 0, "Failed to create parent window\n");
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(types); i++)
|
||||||
|
{
|
||||||
|
/* Test default button */
|
||||||
|
style = types[i] | WS_CHILD | WS_VISIBLE | BS_NOTIFY;
|
||||||
|
button = CreateWindowExA(0, WC_BUTTONA, "test", style, 0, 0, 50, 14, hwnd, (HMENU)ID_BUTTON, 0, NULL);
|
||||||
|
ok(button != NULL, "failed to create a button, 0x%08lx, %p\n", style, hwnd);
|
||||||
|
flush_events();
|
||||||
|
flush_sequence();
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
flush_events();
|
||||||
|
ok_sequence(set_focus_default_seq, "WM_SETFOCUS on default radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test already checked button */
|
||||||
|
button = CreateWindowExA(0, WC_BUTTONA, "test", style, 0, 0, 50, 14, hwnd, (HMENU)ID_BUTTON, 0, NULL);
|
||||||
|
SendMessageA(button, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
flush_events();
|
||||||
|
flush_sequence();
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
flush_events();
|
||||||
|
ok_sequence(set_focus_checked_seq, "WM_SETFOCUS on checked radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test already focused button */
|
||||||
|
button = CreateWindowExA(0, WC_BUTTONA, "test", style, 0, 0, 50, 14, hwnd, (HMENU)ID_BUTTON, 0, NULL);
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
SendMessageA(button, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||||
|
flush_events();
|
||||||
|
flush_sequence();
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
flush_events();
|
||||||
|
ok_sequence(set_focus_default_seq, "WM_SETFOCUS on focused radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test WM_LBUTTONDOWN */
|
||||||
|
button = CreateWindowExA(0, WC_BUTTONA, "test", style, 0, 0, 50, 14, hwnd, (HMENU)ID_BUTTON, 0, NULL);
|
||||||
|
flush_events();
|
||||||
|
flush_sequence();
|
||||||
|
SendMessageA(button, WM_LBUTTONDOWN, 0, 0);
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
|
ok_sequence(WM_LBUTTONDOWN_seq, "WM_LBUTTONDOWN on radiobutton", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
|
||||||
|
/* Test without BS_NOTIFY */
|
||||||
|
style = types[i] | WS_CHILD | WS_VISIBLE;
|
||||||
|
button = CreateWindowExA(0, WC_BUTTONA, "test", style, 0, 0, 50, 14, hwnd, (HMENU)ID_BUTTON, 0, NULL);
|
||||||
|
flush_events();
|
||||||
|
flush_sequence();
|
||||||
|
SendMessageA(button, WM_SETFOCUS, 0, 0);
|
||||||
|
flush_events();
|
||||||
|
ok_sequence(set_focus_without_notify_seq, "WM_SETFOCUS on radiobutton withouth BS_NOTIFY", FALSE);
|
||||||
|
DestroyWindow(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(msg)
|
START_TEST(msg)
|
||||||
{
|
{
|
||||||
char **test_argv;
|
char **test_argv;
|
||||||
|
@ -20585,6 +20682,7 @@ START_TEST(msg)
|
||||||
test_setparent_status();
|
test_setparent_status();
|
||||||
test_InSendMessage();
|
test_InSendMessage();
|
||||||
test_SetFocus();
|
test_SetFocus();
|
||||||
|
test_radiobutton_focus();
|
||||||
test_SetParent();
|
test_SetParent();
|
||||||
test_PostMessage();
|
test_PostMessage();
|
||||||
test_broadcast();
|
test_broadcast();
|
||||||
|
|
Loading…
Reference in a new issue