MSI: add support for Edit boxes in MSI dialogs

Mike McCormack mike at codeweavers.com
Tue Feb 8 08:55:34 CST 2005


ChangeLog:
* add support for Edit boxes in MSI dialogs
* run the message loop when waiting for threads or processes
-------------- next part --------------
? dlls/msi/version.res
Index: dlls/msi/action.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.c,v
retrieving revision 1.82
diff -u -p -r1.82 action.c
--- dlls/msi/action.c	8 Feb 2005 14:26:49 -0000	1.82
+++ dlls/msi/action.c	8 Feb 2005 14:54:40 -0000
@@ -602,6 +602,8 @@ static void ui_progress(MSIPACKAGE *pack
     MSI_RecordSetInteger(row,4,d);
     MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
     msiobj_release(&row->hdr);
+
+    msi_dialog_check_messages(package->dialog, NULL);
 }
 
 static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
@@ -1345,6 +1347,8 @@ UINT ACTION_PerformUIAction(MSIPACKAGE *
     if (!handled)
         handled = ACTION_HandleDialogBox(package, action, &rc);
 
+    msi_dialog_check_messages( package->dialog, NULL );
+
     if (!handled)
     {
         FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
@@ -4985,7 +4989,7 @@ static UINT ACTION_SelfRegModules(MSIPAC
                   c_collen, &si, &info);
 
         if (brc)
-            WaitForSingleObject(info.hProcess,INFINITE);
+            msi_dialog_check_messages(package->dialog, info.hProcess);
  
         HeapFree(GetProcessHeap(),0,filename);
         msiobj_release(&row->hdr);
Index: dlls/msi/custom.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/custom.c,v
retrieving revision 1.5
diff -u -p -r1.5 custom.c
--- dlls/msi/custom.c	8 Feb 2005 14:27:06 -0000	1.5
+++ dlls/msi/custom.c	8 Feb 2005 14:54:40 -0000
@@ -372,9 +372,9 @@ static UINT process_handle(MSIPACKAGE* p
         /* synchronous */
         TRACE("Synchronous Execution of action %s\n",debugstr_w(Name));
         if (ProcessHandle)
-            WaitForSingleObject(ProcessHandle,INFINITE);
+            msi_dialog_check_messages(package->dialog, ProcessHandle);
         else
-            WaitForSingleObject(ThreadHandle,INFINITE);
+            msi_dialog_check_messages(package->dialog, ThreadHandle);
 
         if (!(type & 0x40))
         {
@@ -739,7 +739,8 @@ void ACTION_FinishCustomActions(MSIPACKA
         {
             TRACE("Waiting on action %s\n",
                debugstr_w(package->RunningAction[i].name));
-            WaitForSingleObject(package->RunningAction[i].handle, INFINITE);
+            msi_dialog_check_messages(package->dialog,
+                                      package->RunningAction[i].handle);
         }
 
         HeapFree(GetProcessHeap(),0,package->RunningAction[i].name);
Index: dlls/msi/dialog.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/dialog.c,v
retrieving revision 1.4
diff -u -p -r1.4 dialog.c
--- dlls/msi/dialog.c	8 Feb 2005 12:55:47 -0000	1.4
+++ dlls/msi/dialog.c	8 Feb 2005 14:54:40 -0000
@@ -44,13 +44,13 @@ const static WCHAR szStatic[] = { 'S','t
 
 struct msi_control_tag;
 typedef struct msi_control_tag msi_control;
-typedef UINT (*msi_click_handler)( msi_dialog *, msi_control * );
+typedef UINT (*msi_handler)( msi_dialog *, msi_control *, WPARAM );
 
 struct msi_control_tag
 {
     struct msi_control_tag *next;
     HWND hwnd;
-    msi_click_handler click_handler;
+    msi_handler handler;
     LPWSTR property;
     WCHAR name[1];
 };
@@ -83,9 +83,10 @@ struct control_handler 
     msi_dialog_control_func func;
 };
 
-static UINT msi_dialog_checkbox_click( msi_dialog *, msi_control * );
+static UINT msi_dialog_checkbox_handler( msi_dialog *, msi_control *, WPARAM );
 static void msi_dialog_checkbox_sync_state( msi_dialog *, msi_control * );
-static UINT msi_dialog_button_click( msi_dialog *, msi_control * );
+static UINT msi_dialog_button_handler( msi_dialog *, msi_control *, WPARAM );
+static UINT msi_dialog_edit_handler( msi_dialog *, msi_control *, WPARAM );
 
 
 INT msi_dialog_scale_unit( msi_dialog *dialog, INT val )
@@ -216,12 +217,12 @@ static UINT msi_dialog_build_font_list( 
 static msi_control *msi_dialog_add_control( msi_dialog *dialog,
                 MSIRECORD *rec, LPCWSTR szCls, DWORD style )
 {
-    DWORD x, y, width, height;
+    DWORD x, y, width, height, attributes;
     LPCWSTR text, name;
     LPWSTR font = NULL, title = NULL;
     msi_control *control = NULL;
 
-    style |= WS_CHILD | WS_VISIBLE | WS_GROUP;
+    style |= WS_CHILD | WS_GROUP;
 
     name = MSI_RecordGetString( rec, 2 );
     control = HeapAlloc( GetProcessHeap(), 0,
@@ -229,13 +230,14 @@ static msi_control *msi_dialog_add_contr
     strcpyW( control->name, name );
     control->next = dialog->control_list;
     dialog->control_list = control;
-    control->click_handler = NULL;
+    control->handler = NULL;
     control->property = NULL;
 
     x = MSI_RecordGetInteger( rec, 4 );
     y = MSI_RecordGetInteger( rec, 5 );
     width = MSI_RecordGetInteger( rec, 6 );
     height = MSI_RecordGetInteger( rec, 7 );
+    attributes = MSI_RecordGetInteger( rec, 8 );
     text = MSI_RecordGetString( rec, 10 );
 
     TRACE("Dialog %s control %s\n", debugstr_w(dialog->name), debugstr_w(text));
@@ -245,6 +247,10 @@ static msi_control *msi_dialog_add_contr
     width = msi_dialog_scale_unit( dialog, width );
     height = msi_dialog_scale_unit( dialog, height );
 
+    if( attributes & 1 )
+        style |= WS_VISIBLE;
+    if( ~attributes & 2 )
+        style |= WS_DISABLED;
     if( text )
     {
         font = msi_dialog_get_style( &text );
@@ -275,7 +281,7 @@ static UINT msi_dialog_button_control( m
     TRACE("%p %p\n", dialog, rec);
 
     control = msi_dialog_add_control( dialog, rec, szButton, 0 );
-    control->click_handler = msi_dialog_button_click;
+    control->handler = msi_dialog_button_handler;
 
     return ERROR_SUCCESS;
 }
@@ -290,7 +296,7 @@ static UINT msi_dialog_checkbox_control(
 
     control = msi_dialog_add_control( dialog, rec, szButton,
                                       BS_CHECKBOX | BS_MULTILINE );
-    control->click_handler = msi_dialog_checkbox_click;
+    control->handler = msi_dialog_checkbox_handler;
     prop = MSI_RecordGetString( rec, 9 );
     if( prop )
         control->property = dupstrW( prop );
@@ -328,6 +334,33 @@ static UINT msi_dialog_bitmap_control( m
     return ERROR_SUCCESS;
 }
 
+static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec )
+{
+    static const WCHAR szCombo[] = { 'C','O','M','B','O','B','O','X',0 };
+
+    msi_dialog_add_control( dialog, rec, szCombo,
+                            SS_BITMAP | SS_LEFT | SS_CENTERIMAGE );
+    return ERROR_SUCCESS;
+}
+
+static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
+{
+    const static WCHAR szEdit[] = { 'E','D','I','T',0 };
+    msi_control *control;
+    LPCWSTR prop;
+    LPWSTR val;
+
+    control = msi_dialog_add_control( dialog, rec, szEdit, 0 );
+    control->handler = msi_dialog_edit_handler;
+    prop = MSI_RecordGetString( rec, 9 );
+    if( prop )
+        control->property = dupstrW( prop );
+    val = load_dynamic_property( dialog->package, control->property, NULL );
+    SetWindowTextW( control->hwnd, val );
+    HeapFree( GetProcessHeap(), 0, val );
+    return ERROR_SUCCESS;
+}
+
 static const WCHAR szText[] = { 'T','e','x','t',0 };
 static const WCHAR szButton[] = { 'P','u','s','h','B','u','t','t','o','n',0 };
 static const WCHAR szLine[] = { 'L','i','n','e',0 };
@@ -335,6 +368,9 @@ static const WCHAR szBitmap[] = { 'B','i
 static const WCHAR szCheckBox[] = { 'C','h','e','c','k','B','o','x',0 };
 static const WCHAR szScrollableText[] = {
     'S','c','r','o','l','l','a','b','l','e','T','e','x','t',0 };
+static const WCHAR szComboBox[] = { 'C','o','m','b','o','B','o','x',0 };
+static const WCHAR szEdit[] = { 'E','d','i','t',0 };
+static const WCHAR szMaskedEdit[] = { 'M','a','s','k','e','d','E','d','i','t',0 };
 
 struct control_handler msi_dialog_handler[] =
 {
@@ -344,6 +380,9 @@ struct control_handler msi_dialog_handle
     { szBitmap, msi_dialog_bitmap_control },
     { szCheckBox, msi_dialog_checkbox_control },
     { szScrollableText, msi_dialog_scrolltext_control },
+    { szComboBox, msi_dialog_combo_control },
+    { szEdit, msi_dialog_edit_control },
+    { szMaskedEdit, msi_dialog_edit_control },
 };
 
 #define NUM_CONTROL_TYPES (sizeof msi_dialog_handler/sizeof msi_dialog_handler[0])
@@ -641,7 +680,8 @@ static UINT msi_dialog_control_event( MS
     return ERROR_SUCCESS;
 }
 
-static UINT msi_dialog_button_click( msi_dialog *dialog, msi_control *control )
+static UINT msi_dialog_button_handler( msi_dialog *dialog,
+                                       msi_control *control, WPARAM param )
 {
     static const WCHAR query[] = {
       'S','E','L','E','C','T',' ','*',' ',
@@ -655,6 +695,9 @@ static UINT msi_dialog_button_click( msi
     MSIQUERY *view = NULL;
     UINT r;
 
+    if( HIWORD(param) != BN_CLICKED )
+        return ERROR_SUCCESS;
+
     r = MSI_OpenQuery( dialog->package->db, &view, query,
                        dialog->name, control->name );
     if( r != ERROR_SUCCESS )
@@ -699,11 +742,14 @@ static void msi_dialog_checkbox_sync_sta
                   state ? BST_CHECKED : BST_UNCHECKED, 0 );
 }
 
-static UINT msi_dialog_checkbox_click( msi_dialog *dialog,
-                msi_control *control )
+static UINT msi_dialog_checkbox_handler( msi_dialog *dialog,
+                msi_control *control, WPARAM param )
 {
     UINT state;
 
+    if( HIWORD(param) != BN_CLICKED )
+        return ERROR_SUCCESS;
+
     TRACE("clicked checkbox %s, set %s\n", debugstr_w(control->name),
           debugstr_w(control->property));
 
@@ -712,21 +758,51 @@ static UINT msi_dialog_checkbox_click( m
     msi_dialog_set_checkbox_state( dialog, control, state );
     msi_dialog_checkbox_sync_state( dialog, control );
 
-    return msi_dialog_button_click( dialog, control );
+    return msi_dialog_button_handler( dialog, control, param );
+}
+
+static UINT msi_dialog_edit_handler( msi_dialog *dialog,
+                msi_control *control, WPARAM param )
+{
+    UINT sz, r;
+    LPWSTR buf;
+
+    if( HIWORD(param) != EN_CHANGE )
+        return ERROR_SUCCESS;
+
+    TRACE("edit %s contents changed, set %s\n", debugstr_w(control->name),
+          debugstr_w(control->property));
+
+    sz = 0x20;
+    buf = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
+    while( buf )
+    {
+        r = GetWindowTextW( control->hwnd, buf, sz );
+        if( r < (sz-1) )
+            break;
+            sz *= 2;
+        buf = HeapReAlloc( GetProcessHeap(), 0, buf, sz*sizeof(WCHAR) );
+    }
+
+    MSI_SetPropertyW( dialog->package, control->property, buf );
+
+    HeapFree( GetProcessHeap(), 0, buf );
+
+    return ERROR_SUCCESS;
 }
 
-static LRESULT msi_dialog_handle_click( msi_dialog *dialog, HWND hwnd )
+static LRESULT msi_dialog_oncommand( msi_dialog *dialog, WPARAM param, HWND hwnd )
 {
     msi_control *control;
 
-    TRACE("BN_CLICKED %p %p\n", dialog, hwnd);
+    TRACE("%p %p %08x\n", dialog, hwnd, param);
 
     control = msi_dialog_find_control_by_hwnd( dialog, hwnd );
     if( control )
     {
-        if( control->click_handler )
+        if( control->handler )
         {
-            control->click_handler( dialog, control );
+            control->handler( dialog, control, param );
             msi_dialog_evaluate_control_conditions( dialog );
         }
     }
@@ -746,9 +822,7 @@ static LRESULT WINAPI MSIDialog_WndProc(
         return msi_dialog_oncreate( hwnd, (LPCREATESTRUCTW)lParam );
 
     case WM_COMMAND:
-        if( HIWORD(wParam) == BN_CLICKED )
-            return msi_dialog_handle_click( dialog, (HWND)lParam );
-        break;
+        return msi_dialog_oncommand( dialog, wParam, (HWND)lParam );
 
     case WM_DESTROY:
         dialog->hwnd = NULL;


More information about the wine-patches mailing list