user32: Correct dialog focus behavior.
This commit is contained in:
parent
e3d27c42d9
commit
4b67e6c778
|
@ -55,9 +55,9 @@ static DLGPROC DEFDLG_GetDlgProc( HWND hwnd )
|
|||
* DEFDLG_SetFocus
|
||||
*
|
||||
* Set the focus to a control of the dialog, selecting the text if
|
||||
* the control is an edit dialog.
|
||||
* the control is an edit dialog that has DLGC_HASSETSEL.
|
||||
*/
|
||||
static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
|
||||
static void DEFDLG_SetFocus( HWND hwndCtrl )
|
||||
{
|
||||
if (SendMessageW( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
|
||||
SendMessageW( hwndCtrl, EM_SETSEL, 0, -1 );
|
||||
|
@ -83,7 +83,7 @@ static void DEFDLG_SaveFocus( HWND hwnd )
|
|||
/***********************************************************************
|
||||
* DEFDLG_RestoreFocus
|
||||
*/
|
||||
static void DEFDLG_RestoreFocus( HWND hwnd )
|
||||
static void DEFDLG_RestoreFocus( HWND hwnd, BOOL justActivate )
|
||||
{
|
||||
DIALOGINFO *infoPtr;
|
||||
|
||||
|
@ -92,12 +92,19 @@ static void DEFDLG_RestoreFocus( HWND hwnd )
|
|||
/* Don't set the focus back to controls if EndDialog is already called.*/
|
||||
if (infoPtr->flags & DF_END) return;
|
||||
if (!IsWindow(infoPtr->hwndFocus) || infoPtr->hwndFocus == hwnd) {
|
||||
if (justActivate) return;
|
||||
/* If no saved focus control exists, set focus to the first visible,
|
||||
non-disabled, WS_TABSTOP control in the dialog */
|
||||
infoPtr->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE );
|
||||
/* If there are no WS_TABSTOP controls, set focus to the first visible,
|
||||
non-disabled control in the dialog */
|
||||
if (!infoPtr->hwndFocus) infoPtr->hwndFocus = GetNextDlgGroupItem( hwnd, 0, FALSE );
|
||||
if (!IsWindow( infoPtr->hwndFocus )) return;
|
||||
}
|
||||
DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
|
||||
if (justActivate)
|
||||
SetFocus( infoPtr->hwndFocus );
|
||||
else
|
||||
DEFDLG_SetFocus( infoPtr->hwndFocus );
|
||||
|
||||
/* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
|
||||
sometimes losing focus when receiving WM_SETFOCUS messages. */
|
||||
|
@ -250,12 +257,12 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
|
|||
return DefWindowProcA( hwnd, msg, wParam, lParam );
|
||||
|
||||
case WM_ACTIVATE:
|
||||
if (wParam) DEFDLG_RestoreFocus( hwnd );
|
||||
if (wParam) DEFDLG_RestoreFocus( hwnd, TRUE );
|
||||
else DEFDLG_SaveFocus( hwnd );
|
||||
return 0;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
DEFDLG_RestoreFocus( hwnd );
|
||||
DEFDLG_RestoreFocus( hwnd, FALSE );
|
||||
return 0;
|
||||
|
||||
case DM_SETDEFID:
|
||||
|
@ -280,7 +287,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
|
|||
HWND hwndDest = (HWND)wParam;
|
||||
if (!lParam)
|
||||
hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
|
||||
if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
|
||||
if (hwndDest) DEFDLG_SetFocus( hwndDest );
|
||||
DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -828,7 +828,7 @@ static const char * GetHwndString(HWND hw)
|
|||
return "unknown handle";
|
||||
}
|
||||
|
||||
static void test_initial_focus(void)
|
||||
static void test_focus(void)
|
||||
{
|
||||
/* Test 1:
|
||||
* This test intentionally returns FALSE in response to WM_INITDIALOG
|
||||
|
@ -900,6 +900,8 @@ static void test_initial_focus(void)
|
|||
HRSRC hResource;
|
||||
HANDLE hTemplate;
|
||||
DLGTEMPLATE* pTemplate;
|
||||
HWND hTextbox;
|
||||
DWORD selectionStart = 0xdead, selectionEnd = 0xbeef;
|
||||
|
||||
hResource = FindResourceA(g_hinst,"FOCUS_TEST_DIALOG", RT_DIALOG);
|
||||
hTemplate = LoadResource(g_hinst, hResource);
|
||||
|
@ -912,6 +914,20 @@ static void test_initial_focus(void)
|
|||
ok ((g_hwndInitialFocusT1 == 0),
|
||||
"Focus should not be set for an invisible DS_CONTROL dialog %p.\n", g_hwndInitialFocusT1);
|
||||
|
||||
/* Also make sure that WM_SETFOCUS selects the textbox's text */
|
||||
hTextbox = GetDlgItem(hDlg, 200);
|
||||
SendMessage(hTextbox, WM_SETTEXT, 0, (LPARAM)"Hello world");
|
||||
|
||||
SendMessage(hDlg, WM_SETFOCUS, 0, 0);
|
||||
SendMessage(hTextbox, EM_GETSEL, (WPARAM)&selectionStart, (LPARAM)&selectionEnd);
|
||||
ok(selectionStart == 0 && selectionEnd == 11, "Text selection after WM_SETFOCUS is [%i, %i) expected [0, 11)\n", selectionStart, selectionEnd);
|
||||
|
||||
/* but WM_ACTIVATE does not */
|
||||
SendMessage(hTextbox, EM_SETSEL, 0, 0);
|
||||
SendMessage(hDlg, WM_ACTIVATE, WA_ACTIVE, 0);
|
||||
SendMessage(hTextbox, EM_GETSEL, (WPARAM)&selectionStart, (LPARAM)&selectionEnd);
|
||||
ok(selectionStart == 0 && selectionEnd == 0, "Text selection after WM_ACTIVATE is [%i, %i) expected [0, 0)\n", selectionStart, selectionEnd);
|
||||
|
||||
DestroyWindow(hDlg);
|
||||
}
|
||||
|
||||
|
@ -929,13 +945,25 @@ static void test_initial_focus(void)
|
|||
pTemplate = LockResource(hTemplate);
|
||||
|
||||
hDlg = CreateDialogIndirectParamA(g_hinst, pTemplate, NULL, focusDlgWinProc, 0);
|
||||
g_hwndInitialFocusT1 = GetFocus();
|
||||
ok(hDlg != 0, "Failed to create test dialog.\n");
|
||||
hLabel = GetDlgItem(hDlg, 200);
|
||||
ok (hDlg != 0, "Failed to create test dialog.\n");
|
||||
|
||||
ok ((g_hwndInitialFocusT1 == hLabel),
|
||||
"Focus should have been set to the first control, expected (%p) got (%p).\n",
|
||||
hLabel, g_hwndInitialFocusT1);
|
||||
ok(GetFocus() == hLabel, "Focus not set to label, focus=%p dialog=%p label=%p\n", GetFocus(), hDlg, hLabel);
|
||||
|
||||
DestroyWindow(hDlg);
|
||||
|
||||
/* Also check focus after WM_ACTIVATE and WM_SETFOCUS */
|
||||
hDlg = CreateDialogIndirectParamA(g_hinst, pTemplate, NULL, NULL, 0);
|
||||
ok(hDlg != 0, "Failed to create test dialog.\n");
|
||||
hLabel = GetDlgItem(hDlg, 200);
|
||||
|
||||
SetFocus(NULL);
|
||||
SendMessage(hDlg, WM_ACTIVATE, WA_ACTIVE, 0);
|
||||
ok(GetFocus() == NULL, "Focus set on WM_ACTIVATE, focus=%p dialog=%p label=%p\n", GetFocus(), hDlg, hLabel);
|
||||
|
||||
SetFocus(NULL);
|
||||
SendMessage(hDlg, WM_SETFOCUS, 0, 0);
|
||||
ok(GetFocus() == hLabel, "Focus not set to label on WM_SETFOCUS, focus=%p dialog=%p label=%p\n", GetFocus(), hDlg, hLabel);
|
||||
|
||||
DestroyWindow(hDlg);
|
||||
}
|
||||
|
@ -1404,7 +1432,7 @@ START_TEST(dialog)
|
|||
test_GetNextDlgItem();
|
||||
test_IsDialogMessage();
|
||||
test_WM_NEXTDLGCTL();
|
||||
test_initial_focus();
|
||||
test_focus();
|
||||
test_GetDlgItem();
|
||||
test_GetDlgItemText();
|
||||
test_DialogBoxParamA();
|
||||
|
|
Loading…
Reference in New Issue