Module: wine Branch: master Commit: ad559ca86d8a48e8aebeed326d360edf5306d05f URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=ad559ca86d8a48e8aebeed32...
Author: James Hawkins truiken@gmail.com Date: Thu Aug 31 13:42:57 2006 -0700
msi: Verify the path in the PathEdit control.
---
dlls/msi/dialog.c | 107 +++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 86 insertions(+), 21 deletions(-)
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c index ab58219..824db78 100644 --- a/dlls/msi/dialog.c +++ b/dlls/msi/dialog.c @@ -1388,6 +1388,13 @@ static UINT msi_dialog_progress_bar( msi
/******************** Path Edit ********************************************/
+struct msi_pathedit_info +{ + msi_dialog *dialog; + msi_control *control; + WNDPROC oldproc; +}; + static LPWSTR msi_get_window_text( HWND hwnd ) { UINT sz, r; @@ -1407,21 +1414,63 @@ static LPWSTR msi_get_window_text( HWND return buf; }
-static UINT msi_dialog_pathedit_handler( msi_dialog *dialog, - msi_control *control, WPARAM param ) +static void msi_dialog_update_pathedit( msi_dialog *dialog, msi_control *control ) { - LPWSTR buf, prop; + LPWSTR prop, path; BOOL indirect;
- if( HIWORD(param) != EN_KILLFOCUS ) - return ERROR_SUCCESS; + if (!control && !(control = msi_dialog_find_control_by_type( dialog, szPathEdit ))) + return; + + indirect = control->attributes & msidbControlAttributesIndirect; + prop = msi_dialog_dup_property( dialog, control->property, indirect ); + + path = msi_dup_property( dialog->package, prop ); + SetWindowTextW( control->hwnd, path ); + SendMessageW( control->hwnd, EM_SETSEL, 0, -1 ); + + msi_free( path ); + msi_free( prop ); +} + +/* FIXME: test when this should fail */ +static BOOL msi_dialog_verify_path( LPWSTR path ) +{ + if ( !lstrlenW( path ) ) + return FALSE; + + if ( PathIsRelativeW( path ) ) + return FALSE; + + return TRUE; +} + +/* returns TRUE if the path is valid, FALSE otherwise */ +static BOOL msi_dialog_onkillfocus( msi_dialog *dialog, msi_control *control ) +{ + LPWSTR buf, prop; + BOOL indirect; + BOOL valid;
indirect = control->attributes & msidbControlAttributesIndirect; prop = msi_dialog_dup_property( dialog, control->property, indirect );
- /* FIXME: verify the new path */ buf = msi_get_window_text( control->hwnd ); - MSI_SetPropertyW( dialog->package, prop, buf ); + + if ( !msi_dialog_verify_path( buf ) ) + { + /* FIXME: display an error message box */ + ERR("Invalid path %s\n", debugstr_w( buf )); + valid = FALSE; + SetFocus( control->hwnd ); + } + else + { + valid = TRUE; + MSI_SetPropertyW( dialog->package, prop, buf ); + } + + msi_dialog_update_pathedit( dialog, control );
TRACE("edit %s contents changed, set %s\n", debugstr_w(control->name), debugstr_w(prop)); @@ -1429,40 +1478,56 @@ static UINT msi_dialog_pathedit_handler( msi_free( buf ); msi_free( prop );
- return ERROR_SUCCESS; + return valid; }
-static void msi_dialog_update_pathedit( msi_dialog *dialog, msi_control *control ) +static LRESULT WINAPI MSIPathEdit_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - LPWSTR prop, path; - BOOL indirect; + struct msi_pathedit_info *info = GetPropW(hWnd, szButtonData); + LRESULT r = 0;
- if (!control && !(control = msi_dialog_find_control_by_type( dialog, szPathEdit ) )) - return; + TRACE("%p %04x %08x %08lx\n", hWnd, msg, wParam, lParam);
- indirect = control->attributes & msidbControlAttributesIndirect; - prop = msi_dialog_dup_property( dialog, control->property, indirect ); + if ( msg == WM_KILLFOCUS ) + { + /* if the path is invalid, don't handle this message */ + if ( !msi_dialog_onkillfocus( info->dialog, info->control ) ) + return 0; + }
- path = msi_dup_property( dialog->package, prop ); - SetWindowTextW( control->hwnd, path ); - SendMessageW( control->hwnd, EM_SETSEL, 0, -1 ); + r = CallWindowProcW(info->oldproc, hWnd, msg, wParam, lParam);
- msi_free( path ); - msi_free( prop ); + if ( msg == WM_NCDESTROY ) + { + msi_free( info ); + RemovePropW( hWnd, szButtonData ); + } + + return r; }
static UINT msi_dialog_pathedit_control( msi_dialog *dialog, MSIRECORD *rec ) { + struct msi_pathedit_info *info; msi_control *control; LPCWSTR prop;
+ info = msi_alloc( sizeof *info ); + if (!info) + return ERROR_FUNCTION_FAILED; + control = msi_dialog_add_control( dialog, rec, szEdit, WS_BORDER | WS_TABSTOP ); - control->handler = msi_dialog_pathedit_handler; control->attributes = MSI_RecordGetInteger( rec, 8 ); prop = MSI_RecordGetString( rec, 9 ); control->property = msi_dialog_dup_property( dialog, prop, FALSE );
+ info->dialog = dialog; + info->control = control; + info->oldproc = (WNDPROC) SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC, + (LONG_PTR)MSIPathEdit_WndProc ); + SetPropW( control->hwnd, szButtonData, info ); + msi_dialog_update_pathedit( dialog, control );
return ERROR_SUCCESS;