diff --git a/controls/button.c b/controls/button.c index 9c8b60d1944..1fd77983abc 100644 --- a/controls/button.c +++ b/controls/button.c @@ -187,6 +187,10 @@ LRESULT WINAPI ButtonWndProc( HWND32 hWnd, UINT32 uMsg, case WM_SETFOCUS: infoPtr->state |= BUTTON_HASFOCUS; + if (style == BS_AUTORADIOBUTTON) + { + SendMessage32A( hWnd, BM_SETCHECK32, 1, 0 ); + } PAINT_BUTTON( wndPtr, style, ODA_FOCUS ); break; @@ -218,6 +222,13 @@ LRESULT WINAPI ButtonWndProc( HWND32 hWnd, UINT32 uMsg, if (wParam > maxCheckState[style]) wParam = maxCheckState[style]; if ((infoPtr->state & 3) != wParam) { + if ((style == BS_RADIOBUTTON) || (style == BS_AUTORADIOBUTTON)) + { + if (wParam) + wndPtr->dwStyle |= WS_TABSTOP; + else + wndPtr->dwStyle &= ~WS_TABSTOP; + } infoPtr->state = (infoPtr->state & ~3) | wParam; PAINT_BUTTON( wndPtr, style, ODA_SELECT ); } diff --git a/controls/menu.c b/controls/menu.c index 1cbb1c4879f..abefac9eb64 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -566,8 +566,13 @@ static UINT32 MENU_FindItemByKey( HWND32 hwndOwner, HMENU32 hmenu, { if (item->text && (IS_STRING_ITEM(item->fType))) { - char *p = strchr( item->text, '&' ); - if (p && (p[1] != '&') && (toupper(p[1]) == key)) return i; + char *p = item->text - 2; + do + { + p = strchr (p + 2, '&'); + } + while (p != NULL && p [1] == '&'); + if (p && (toupper(p[1]) == key)) return i; } } } @@ -2364,11 +2369,6 @@ static BOOL32 MENU_TrackMenu( HMENU32 hmenu, UINT32 wFlags, INT32 x, INT32 y, MENU_KeyRight( &mt ); break; - case VK_SPACE: - case VK_RETURN: - fEndMenu |= !MENU_ExecFocusedItem( &mt, mt.hCurrentMenu ); - break; - case VK_ESCAPE: fEndMenu = TRUE; break; @@ -2392,6 +2392,12 @@ static BOOL32 MENU_TrackMenu( HMENU32 hmenu, UINT32 wFlags, INT32 x, INT32 y, { UINT32 pos; + if (msg.wParam == '\r' || msg.wParam == ' ') + { + fEndMenu |= !MENU_ExecFocusedItem( &mt, mt.hCurrentMenu ); + break; + } + /* Hack to avoid control chars. */ /* We will find a better way real soon... */ if ((msg.wParam <= 32) || (msg.wParam >= 127)) break; diff --git a/windows/dialog.c b/windows/dialog.c index ae82fdfa518..4bf74b51100 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -1004,16 +1004,97 @@ BOOL32 WINAPI EndDialog32( HWND32 hwnd, INT32 retval ) } +/*********************************************************************** + * DIALOG_IsAccelerator + */ +static BOOL32 DIALOG_IsAccelerator( HWND32 hwnd, HWND32 hwndDlg, WPARAM32 vKey ) +{ + HWND32 hwndControl = hwnd; + WND *wndPtr; + BOOL32 RetVal = FALSE; + INT32 dlgCode; + + if (vKey == VK_SPACE) + { + dlgCode = SendMessage32A( hwndControl, WM_GETDLGCODE, 0, 0 ); + if (dlgCode & DLGC_BUTTON) + { + SendMessage32A( hwndControl, WM_LBUTTONDOWN, 0, 0); + SendMessage32A( hwndControl, WM_LBUTTONUP, 0, 0); + RetVal = TRUE; + } + } + else + { + do + { + wndPtr = WIN_FindWndPtr( hwndControl ); + if (wndPtr != NULL && wndPtr->text != NULL && + (wndPtr->dwStyle & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE) + { + dlgCode = SendMessage32A( hwndControl, WM_GETDLGCODE, 0, 0 ); + if (dlgCode & (DLGC_BUTTON | DLGC_STATIC)) + { + /* find the accelerator key */ + LPSTR p = wndPtr->text - 2; + do + { + p = strchr( p + 2, '&' ); + } + while (p != NULL && p[1] == '&'); + + /* and check if it's the one we're looking for */ + if (p != NULL && toupper( p[1] ) == toupper( vKey ) ) + { + if ((dlgCode & DLGC_STATIC) || + (wndPtr->dwStyle & 0x0f) == BS_GROUPBOX ) + { + /* set focus to the control */ + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, + hwndControl, 1); + /* and bump it on to next */ + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, 0, 0); + } + else if (dlgCode & + (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON)) + { + /* send command message as from the control */ + SendMessage32A( hwndDlg, WM_COMMAND, + MAKEWPARAM( LOWORD(wndPtr->wIDmenu), + BN_CLICKED ), + (LPARAM)hwndControl ); + } + else + { + /* click the control */ + SendMessage32A( hwndControl, WM_LBUTTONDOWN, 0, 0); + SendMessage32A( hwndControl, WM_LBUTTONUP, 0, 0); + } + RetVal = TRUE; + break; + } + } + } + hwndControl = GetWindow32( hwndControl, GW_HWNDNEXT ); + if (!hwndControl) + { + hwndControl = GetWindow32( hwndDlg, GW_CHILD ); + } + } + while (hwndControl != hwnd); + } + return RetVal; +} + + /*********************************************************************** * DIALOG_IsDialogMessage */ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, UINT32 message, WPARAM32 wParam, LPARAM lParam, BOOL32 *translate, - BOOL32 *dispatch ) + BOOL32 *dispatch, INT32 dlgCode ) { - INT32 dlgCode; - *translate = *dispatch = FALSE; if (message == WM_PAINT) @@ -1029,7 +1110,6 @@ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, (message != WM_CHAR)) return FALSE; - dlgCode = SendMessage32A( hwnd, WM_GETDLGCODE, 0, 0 ); if (dlgCode & DLGC_WANTMESSAGE) { *translate = *dispatch = TRUE; @@ -1039,7 +1119,6 @@ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, switch(message) { case WM_KEYDOWN: - if (dlgCode & DLGC_WANTALLKEYS) break; switch(wParam) { case VK_TAB: @@ -1053,20 +1132,14 @@ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, case VK_RIGHT: case VK_DOWN: - if (!(dlgCode & DLGC_WANTARROWS)) - { - SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(), - FALSE ) ); - return TRUE; - } - break; - case VK_LEFT: case VK_UP: if (!(dlgCode & DLGC_WANTARROWS)) { - SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(), - TRUE ) ); + BOOL32 fPrevious = (wParam == VK_LEFT || wParam == VK_UP); + HWND32 hwndNext = + GetNextDlgGroupItem32 (hwndDlg, GetFocus32(), fPrevious ); + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, hwndNext, 1 ); return TRUE; } break; @@ -1074,34 +1147,39 @@ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, case VK_ESCAPE: SendMessage32A( hwndDlg, WM_COMMAND, IDCANCEL, (LPARAM)GetDlgItem32( hwndDlg, IDCANCEL ) ); - break; + return TRUE; case VK_RETURN: { DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 ); if (HIWORD(dw) == DC_HASDEFID) + { SendMessage32A( hwndDlg, WM_COMMAND, MAKEWPARAM( LOWORD(dw), BN_CLICKED ), (LPARAM)GetDlgItem32(hwndDlg, LOWORD(dw))); + } else + { SendMessage32A( hwndDlg, WM_COMMAND, IDOK, (LPARAM)GetDlgItem32( hwndDlg, IDOK ) ); + + } } - break; - - default: - *translate = TRUE; - break; + return TRUE; } - break; /* case WM_KEYDOWN */ + *translate = TRUE; + break; /* case WM_KEYDOWN */ - case WM_CHAR: - if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break; - break; + if (dlgCode & DLGC_WANTCHARS) break; + /* drop through */ case WM_SYSCHAR: - if (dlgCode & DLGC_WANTALLKEYS) break; + if (DIALOG_IsAccelerator( hwnd, hwndDlg, wParam )) + { + /* don't translate or dispatch */ + return TRUE; + } break; } @@ -1118,13 +1196,16 @@ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, LPMSG16 msg ) { BOOL32 ret, translate, dispatch; + INT32 dlgCode; if ((hwndDlg != msg->hwnd) && !IsChild16( hwndDlg, msg->hwnd )) return FALSE; + + dlgCode = SendMessage16( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, msg->wParam, msg->lParam, - &translate, &dispatch ); + &translate, &dispatch, dlgCode ); if (translate) TranslateMessage16( msg ); if (dispatch) DispatchMessage16( msg ); return ret; @@ -1137,13 +1218,15 @@ BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, LPMSG16 msg ) BOOL32 WINAPI IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg ) { BOOL32 ret, translate, dispatch; + INT32 dlgCode; if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd )) return FALSE; + dlgCode = SendMessage32A( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, msg->wParam, msg->lParam, - &translate, &dispatch ); + &translate, &dispatch, dlgCode ); if (translate) TranslateMessage32( msg ); if (dispatch) DispatchMessage32A( msg ); return ret; @@ -1156,13 +1239,15 @@ BOOL32 WINAPI IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg ) BOOL32 WINAPI IsDialogMessage32W( HWND32 hwndDlg, LPMSG32 msg ) { BOOL32 ret, translate, dispatch; + INT32 dlgCode; if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd )) return FALSE; + dlgCode = SendMessage32W( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, msg->wParam, msg->lParam, - &translate, &dispatch ); + &translate, &dispatch, dlgCode ); if (translate) TranslateMessage32( msg ); if (dispatch) DispatchMessage32W( msg ); return ret;