Add support for radio buttons.
This commit is contained in:
parent
dd170db028
commit
64db533173
|
@ -41,6 +41,9 @@ const WCHAR szMsiDialogClass[] = {
|
||||||
'M','s','i','D','i','a','l','o','g','C','l','o','s','e','C','l','a','s','s',0
|
'M','s','i','D','i','a','l','o','g','C','l','o','s','e','C','l','a','s','s',0
|
||||||
};
|
};
|
||||||
const static WCHAR szStatic[] = { 'S','t','a','t','i','c',0 };
|
const static WCHAR szStatic[] = { 'S','t','a','t','i','c',0 };
|
||||||
|
const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 };
|
||||||
|
|
||||||
|
const static WCHAR szButtonData[] = { 'M','S','I','D','A','T','A',0 };
|
||||||
|
|
||||||
struct msi_control_tag;
|
struct msi_control_tag;
|
||||||
typedef struct msi_control_tag msi_control;
|
typedef struct msi_control_tag msi_control;
|
||||||
|
@ -83,10 +86,19 @@ struct control_handler
|
||||||
msi_dialog_control_func func;
|
msi_dialog_control_func func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
msi_dialog* dialog;
|
||||||
|
msi_control *parent;
|
||||||
|
DWORD attributes;
|
||||||
|
} radio_button_group_descr;
|
||||||
|
|
||||||
static UINT msi_dialog_checkbox_handler( msi_dialog *, msi_control *, WPARAM );
|
static UINT msi_dialog_checkbox_handler( msi_dialog *, msi_control *, WPARAM );
|
||||||
static void msi_dialog_checkbox_sync_state( msi_dialog *, msi_control * );
|
static void msi_dialog_checkbox_sync_state( msi_dialog *, msi_control * );
|
||||||
static UINT msi_dialog_button_handler( msi_dialog *, msi_control *, WPARAM );
|
static UINT msi_dialog_button_handler( msi_dialog *, msi_control *, WPARAM );
|
||||||
static UINT msi_dialog_edit_handler( msi_dialog *, msi_control *, WPARAM );
|
static UINT msi_dialog_edit_handler( msi_dialog *, msi_control *, WPARAM );
|
||||||
|
static UINT msi_dialog_radiogroup_handler( msi_dialog *, msi_control *, WPARAM param );
|
||||||
|
static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
|
||||||
INT msi_dialog_scale_unit( msi_dialog *dialog, INT val )
|
INT msi_dialog_scale_unit( msi_dialog *dialog, INT val )
|
||||||
|
@ -275,7 +287,6 @@ static UINT msi_dialog_text_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
|
|
||||||
static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec )
|
static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
{
|
{
|
||||||
const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 };
|
|
||||||
msi_control *control;
|
msi_control *control;
|
||||||
|
|
||||||
TRACE("%p %p\n", dialog, rec);
|
TRACE("%p %p\n", dialog, rec);
|
||||||
|
@ -288,7 +299,6 @@ static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
|
|
||||||
static UINT msi_dialog_checkbox_control( msi_dialog *dialog, MSIRECORD *rec )
|
static UINT msi_dialog_checkbox_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
{
|
{
|
||||||
const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 };
|
|
||||||
msi_control *control;
|
msi_control *control;
|
||||||
LPCWSTR prop;
|
LPCWSTR prop;
|
||||||
|
|
||||||
|
@ -367,17 +377,119 @@ static UINT msi_dialog_pathedit_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
return msi_dialog_edit_control( dialog, rec );
|
return msi_dialog_edit_control( dialog, rec );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec )
|
static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param )
|
||||||
{
|
{
|
||||||
LPCWSTR name;
|
radio_button_group_descr *group = (radio_button_group_descr *)param;
|
||||||
|
msi_dialog *dialog = group->dialog;
|
||||||
|
msi_control *control;
|
||||||
|
LPCWSTR prop;
|
||||||
|
DWORD x, y, width, height, style;
|
||||||
|
DWORD attributes = group->attributes;
|
||||||
|
LPCWSTR text, name;
|
||||||
|
LPWSTR font = NULL, title = NULL;
|
||||||
|
|
||||||
|
style = WS_CHILD | BS_AUTORADIOBUTTON | BS_MULTILINE;
|
||||||
|
name = MSI_RecordGetString( rec, 3 );
|
||||||
|
control = HeapAlloc( GetProcessHeap(), 0,
|
||||||
|
sizeof *control + strlenW(name)*sizeof(WCHAR) );
|
||||||
|
strcpyW( control->name, name );
|
||||||
|
control->next = dialog->control_list;
|
||||||
|
dialog->control_list = control;
|
||||||
|
|
||||||
|
x = MSI_RecordGetInteger( rec, 4 );
|
||||||
|
y = MSI_RecordGetInteger( rec, 5 );
|
||||||
|
width = MSI_RecordGetInteger( rec, 6 );
|
||||||
|
height = MSI_RecordGetInteger( rec, 7 );
|
||||||
|
text = MSI_RecordGetString( rec, 8 );
|
||||||
|
|
||||||
|
x = msi_dialog_scale_unit( dialog, x );
|
||||||
|
y = msi_dialog_scale_unit( dialog, y );
|
||||||
|
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 );
|
||||||
|
deformat_string( dialog->package, text, &title );
|
||||||
|
}
|
||||||
|
|
||||||
|
control->hwnd = CreateWindowW( szButton, title, style, x, y, width, height,
|
||||||
|
group->parent->hwnd, NULL, NULL, NULL );
|
||||||
|
|
||||||
|
TRACE("Dialog %s control %s hwnd %p\n", debugstr_w(dialog->name), debugstr_w(text), control->hwnd);
|
||||||
|
|
||||||
|
msi_dialog_set_font( dialog, control->hwnd,
|
||||||
|
font ? font : dialog->default_font );
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, font );
|
||||||
|
HeapFree( GetProcessHeap(), 0, title );
|
||||||
|
|
||||||
|
control->handler = msi_dialog_radiogroup_handler;
|
||||||
|
|
||||||
|
prop = MSI_RecordGetString( rec, 1 );
|
||||||
|
if( prop )
|
||||||
|
control->property = dupstrW( prop );
|
||||||
|
|
||||||
name = MSI_RecordGetString( rec, 2 );
|
|
||||||
FIXME("Radio group %s\n", debugstr_w( name ) );
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
|
{
|
||||||
|
static const WCHAR query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ',
|
||||||
|
'F','R','O','M',' ','R','a','d','i','o','B','u','t','t','o','n',' ',
|
||||||
|
'W','H','E','R','E',' ',
|
||||||
|
'`','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
|
||||||
|
UINT r;
|
||||||
|
LPCWSTR prop;
|
||||||
|
msi_control *control;
|
||||||
|
MSIQUERY *view = NULL;
|
||||||
|
radio_button_group_descr group;
|
||||||
|
MSIPACKAGE *package = dialog->package;
|
||||||
|
|
||||||
|
prop = MSI_RecordGetString( rec, 9 );
|
||||||
|
|
||||||
|
TRACE("%p %p %s\n", dialog, rec, debugstr_w( prop ));
|
||||||
|
|
||||||
|
/* Create parent group box to hold radio buttons */
|
||||||
|
control = msi_dialog_add_control( dialog, rec, szButton, BS_OWNERDRAW );
|
||||||
|
|
||||||
|
if (control->hwnd)
|
||||||
|
{
|
||||||
|
WNDPROC oldproc = (WNDPROC) SetWindowLongPtrW(control->hwnd, GWLP_WNDPROC,
|
||||||
|
(LONG_PTR)MSIRadioGroup_WndProc);
|
||||||
|
SetPropW(control->hwnd, szButtonData, oldproc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( prop )
|
||||||
|
control->property = dupstrW( prop );
|
||||||
|
|
||||||
|
/* query the Radio Button table for all control in this group */
|
||||||
|
r = MSI_OpenQuery( package->db, &view, query, prop );
|
||||||
|
if( r != ERROR_SUCCESS )
|
||||||
|
{
|
||||||
|
ERR("query failed for dialog %s radio group %s\n",
|
||||||
|
debugstr_w(dialog->name), debugstr_w(prop));
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
group.dialog = dialog;
|
||||||
|
group.parent = control;
|
||||||
|
group.attributes = MSI_RecordGetInteger( rec, 8 );
|
||||||
|
|
||||||
|
r = MSI_IterateRecords( view, 0, msi_dialog_create_radiobutton, &group );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static const WCHAR szText[] = { 'T','e','x','t',0 };
|
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 szPushButton[] = { 'P','u','s','h','B','u','t','t','o','n',0 };
|
||||||
static const WCHAR szLine[] = { 'L','i','n','e',0 };
|
static const WCHAR szLine[] = { 'L','i','n','e',0 };
|
||||||
static const WCHAR szBitmap[] = { 'B','i','t','m','a','p',0 };
|
static const WCHAR szBitmap[] = { 'B','i','t','m','a','p',0 };
|
||||||
static const WCHAR szCheckBox[] = { 'C','h','e','c','k','B','o','x',0 };
|
static const WCHAR szCheckBox[] = { 'C','h','e','c','k','B','o','x',0 };
|
||||||
|
@ -393,7 +505,7 @@ static const WCHAR szRadioButtonGroup[] = {
|
||||||
struct control_handler msi_dialog_handler[] =
|
struct control_handler msi_dialog_handler[] =
|
||||||
{
|
{
|
||||||
{ szText, msi_dialog_text_control },
|
{ szText, msi_dialog_text_control },
|
||||||
{ szButton, msi_dialog_button_control },
|
{ szPushButton, msi_dialog_button_control },
|
||||||
{ szLine, msi_dialog_line_control },
|
{ szLine, msi_dialog_line_control },
|
||||||
{ szBitmap, msi_dialog_bitmap_control },
|
{ szBitmap, msi_dialog_bitmap_control },
|
||||||
{ szCheckBox, msi_dialog_checkbox_control },
|
{ szCheckBox, msi_dialog_checkbox_control },
|
||||||
|
@ -811,6 +923,20 @@ static UINT msi_dialog_edit_handler( msi_dialog *dialog,
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT msi_dialog_radiogroup_handler( msi_dialog *dialog,
|
||||||
|
msi_control *control, WPARAM param )
|
||||||
|
{
|
||||||
|
if( HIWORD(param) != BN_CLICKED )
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
TRACE("clicked radio button %s, set %s\n", debugstr_w(control->name),
|
||||||
|
debugstr_w(control->property));
|
||||||
|
|
||||||
|
MSI_SetPropertyW( dialog->package, control->property, control->name );
|
||||||
|
|
||||||
|
return msi_dialog_button_handler( dialog, control, param );
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT msi_dialog_oncommand( msi_dialog *dialog, WPARAM param, HWND hwnd )
|
static LRESULT msi_dialog_oncommand( msi_dialog *dialog, WPARAM param, HWND hwnd )
|
||||||
{
|
{
|
||||||
msi_control *control;
|
msi_control *control;
|
||||||
|
@ -836,6 +962,7 @@ static LRESULT WINAPI MSIDialog_WndProc( HWND hwnd, UINT msg,
|
||||||
{
|
{
|
||||||
msi_dialog *dialog = (LPVOID) GetWindowLongPtrW( hwnd, GWLP_USERDATA );
|
msi_dialog *dialog = (LPVOID) GetWindowLongPtrW( hwnd, GWLP_USERDATA );
|
||||||
|
|
||||||
|
TRACE(" 0x%04x\n", msg);
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
|
@ -991,3 +1118,15 @@ void msi_dialog_unregister_class( void )
|
||||||
{
|
{
|
||||||
UnregisterClassW( szMsiDialogClass, NULL );
|
UnregisterClassW( szMsiDialogClass, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
WNDPROC oldproc = (WNDPROC) GetPropW(hWnd, szButtonData);
|
||||||
|
|
||||||
|
TRACE("hWnd %p msg %04x wParam 0x%08x lParam 0x%08lx\n", hWnd, msg, wParam, lParam);
|
||||||
|
|
||||||
|
if (msg == WM_COMMAND) /* Forward notifications to dialog */
|
||||||
|
SendMessageW(GetParent(hWnd), msg, wParam, lParam);
|
||||||
|
|
||||||
|
return CallWindowProcW(oldproc, hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue