msi: Build a proper tab chain by walking through the controls list.

Simply changing Z-order as we encounter windows is not sufficient to
ensure correct ordering, we have to rebuild the list from scratch.
This commit is contained in:
Alexandre Julliard 2009-07-15 14:22:14 +02:00
parent bd7a2e70b0
commit 2c5bd49297
1 changed files with 23 additions and 27 deletions

View File

@ -417,7 +417,7 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog,
return NULL;
strcpyW( control->name, name );
list_add_head( &dialog->controls, &control->entry );
list_add_tail( &dialog->controls, &control->entry );
control->handler = NULL;
control->update = NULL;
control->property = NULL;
@ -3002,37 +3002,34 @@ static void msi_dialog_adjust_dialog_pos( msi_dialog *dialog, MSIRECORD *rec, LP
AdjustWindowRect( pos, style, FALSE );
}
static BOOL msi_control_set_next( msi_control *control, msi_control *next )
static void msi_dialog_set_tab_order( msi_dialog *dialog, LPCWSTR first )
{
return SetWindowPos( next->hwnd, control->hwnd, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW |
SWP_NOREPOSITION | SWP_NOSENDCHANGING | SWP_NOSIZE );
}
struct list tab_chain;
msi_control *control;
HWND prev = HWND_TOP;
static UINT msi_dialog_set_tab_order( msi_dialog *dialog )
{
msi_control *control, *tab_next;
list_init( &tab_chain );
if (!(control = msi_dialog_find_control( dialog, first ))) return;
LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry )
dialog->hWndFocus = control->hwnd;
while (control)
{
tab_next = msi_dialog_find_control( dialog, control->tabnext );
if( !tab_next )
continue;
msi_control_set_next( control, tab_next );
list_remove( &control->entry );
list_add_tail( &tab_chain, &control->entry );
if (!control->tabnext) break;
control = msi_dialog_find_control( dialog, control->tabnext );
}
return ERROR_SUCCESS;
}
LIST_FOR_EACH_ENTRY( control, &tab_chain, msi_control, entry )
{
SetWindowPos( control->hwnd, prev, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW |
SWP_NOREPOSITION | SWP_NOSENDCHANGING | SWP_NOSIZE );
prev = control->hwnd;
}
static void msi_dialog_set_first_control( msi_dialog* dialog, LPCWSTR name )
{
msi_control *control;
control = msi_dialog_find_control( dialog, name );
if( control )
dialog->hWndFocus = control->hwnd;
else
dialog->hWndFocus = NULL;
/* put them back on the main list */
list_move_head( &dialog->controls, &tab_chain );
}
static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs )
@ -3082,8 +3079,7 @@ static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs )
msi_dialog_build_font_list( dialog );
msi_dialog_fill_controls( dialog );
msi_dialog_evaluate_control_conditions( dialog );
msi_dialog_set_tab_order( dialog );
msi_dialog_set_first_control( dialog, MSI_RecordGetString( rec, 8 ) );
msi_dialog_set_tab_order( dialog, MSI_RecordGetString( rec, 8 ) );
msiobj_release( &rec->hdr );
return 0;