@@ -66,6 +66,7 @@ struct msi_control_tag
6666 LPWSTR value ;
6767 HBITMAP hBitmap ;
6868 HICON hIcon ;
69+ HIMAGELIST hImageList ;
6970 LPWSTR tabnext ;
7071 LPWSTR type ;
7172 HMODULE hDll ;
@@ -159,6 +160,7 @@ static const WCHAR szVolumeSelectCombo[] = { 'V','o','l','u','m','e','S','e','l'
159160static const WCHAR szSelectionDescription [] = {'S' ,'e' ,'l' ,'e' ,'c' ,'t' ,'i' ,'o' ,'n' ,'D' ,'e' ,'s' ,'c' ,'r' ,'i' ,'p' ,'t' ,'i' ,'o' ,'n' ,0 };
160161static const WCHAR szSelectionPath [] = {'S' ,'e' ,'l' ,'e' ,'c' ,'t' ,'i' ,'o' ,'n' ,'P' ,'a' ,'t' ,'h' ,0 };
161162static const WCHAR szHyperLink [] = {'H' ,'y' ,'p' ,'e' ,'r' ,'L' ,'i' ,'n' ,'k' ,0 };
163+ static const WCHAR szListView [] = {'L' ,'i' ,'s' ,'t' ,'V' ,'i' ,'e' ,'w' ,0 };
162164
163165/* dialog sequencing */
164166
@@ -401,6 +403,8 @@ static void msi_destroy_control( msi_control *t )
401403 DeleteObject ( t -> hBitmap );
402404 if ( t -> hIcon )
403405 DestroyIcon ( t -> hIcon );
406+ if ( t -> hImageList )
407+ ImageList_Destroy ( t -> hImageList );
404408 msi_free ( t -> tabnext );
405409 msi_free ( t -> type );
406410 if (t -> hDll )
@@ -431,6 +435,7 @@ static msi_control *dialog_create_window( msi_dialog *dialog, MSIRECORD *rec, DW
431435 control -> value = NULL ;
432436 control -> hBitmap = NULL ;
433437 control -> hIcon = NULL ;
438+ control -> hImageList = NULL ;
434439 control -> hDll = NULL ;
435440 control -> tabnext = strdupW ( MSI_RecordGetString ( rec , 11 ) );
436441 control -> type = strdupW ( MSI_RecordGetString ( rec , 3 ) );
@@ -3522,6 +3527,107 @@ static UINT msi_dialog_hyperlink( msi_dialog *dialog, MSIRECORD *rec )
35223527 return ERROR_SUCCESS ;
35233528}
35243529
3530+ /******************** ListView *****************************************/
3531+
3532+ struct listview_param
3533+ {
3534+ msi_dialog * dialog ;
3535+ msi_control * control ;
3536+ };
3537+
3538+ static UINT msi_dialog_listview_handler ( msi_dialog * dialog , msi_control * control , WPARAM param )
3539+ {
3540+ NMHDR * nmhdr = (NMHDR * )param ;
3541+
3542+ FIXME ("code %#x (%d)\n" , nmhdr -> code , nmhdr -> code );
3543+
3544+ return ERROR_SUCCESS ;
3545+ }
3546+
3547+ static UINT msi_listview_add_item ( MSIRECORD * rec , LPVOID param )
3548+ {
3549+ struct listview_param * lv_param = (struct listview_param * )param ;
3550+ LPCWSTR text , binary ;
3551+ LVITEMW item ;
3552+ HICON hIcon ;
3553+
3554+ text = MSI_RecordGetString ( rec , 4 );
3555+ binary = MSI_RecordGetString ( rec , 5 );
3556+ hIcon = msi_load_icon ( lv_param -> dialog -> package -> db , binary , 0 );
3557+
3558+ TRACE ("Adding: text %s, binary %s, icon %p\n" , debugstr_w (text ), debugstr_w (binary ), hIcon );
3559+
3560+ memset ( & item , 0 , sizeof (item ) );
3561+ item .mask = LVIF_TEXT | LVIF_IMAGE ;
3562+ deformat_string ( lv_param -> dialog -> package , text , & item .pszText );
3563+ item .iImage = ImageList_AddIcon ( lv_param -> control -> hImageList , hIcon );
3564+ item .iItem = item .iImage ;
3565+ SendMessageW ( lv_param -> control -> hwnd , LVM_INSERTITEMW , 0 , (LPARAM )& item );
3566+
3567+ DestroyIcon ( hIcon );
3568+
3569+ return ERROR_SUCCESS ;
3570+ }
3571+
3572+ static UINT msi_listview_add_items ( msi_dialog * dialog , msi_control * control )
3573+ {
3574+ static const WCHAR query [] = {
3575+ 'S' ,'E' ,'L' ,'E' ,'C' ,'T' ,' ' ,'*' ,' ' ,'F' ,'R' ,'O' ,'M' ,' ' ,
3576+ '`' ,'L' ,'i' ,'s' ,'t' ,'V' ,'i' ,'e' ,'w' ,'`' ,' ' ,'W' ,'H' ,'E' ,'R' ,'E' ,' ' ,
3577+ '`' ,'P' ,'r' ,'o' ,'p' ,'e' ,'r' ,'t' ,'y' ,'`' ,' ' ,'=' ,' ' ,'\'' ,'%' ,'s' ,'\'' ,' ' ,
3578+ 'O' ,'R' ,'D' ,'E' ,'R' ,' ' ,'B' ,'Y' ,' ' ,'`' ,'O' ,'r' ,'d' ,'e' ,'r' ,'`' ,0 };
3579+ MSIQUERY * view ;
3580+ struct listview_param lv_param = { dialog , control };
3581+
3582+ if (MSI_OpenQuery ( dialog -> package -> db , & view , query , control -> property ) == ERROR_SUCCESS )
3583+ {
3584+ MSI_IterateRecords ( view , NULL , msi_listview_add_item , & lv_param );
3585+ msiobj_release ( & view -> hdr );
3586+ }
3587+
3588+ return ERROR_SUCCESS ;
3589+ }
3590+
3591+ static UINT msi_dialog_listview ( msi_dialog * dialog , MSIRECORD * rec )
3592+ {
3593+ msi_control * control ;
3594+ LPCWSTR prop ;
3595+ DWORD style , attributes ;
3596+ LVCOLUMNW col ;
3597+ RECT rc ;
3598+
3599+ style = LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SINGLESEL |
3600+ LVS_SHOWSELALWAYS | WS_VSCROLL | WS_HSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD ;
3601+ attributes = MSI_RecordGetInteger ( rec , 8 );
3602+ if ( ~attributes & msidbControlAttributesSorted )
3603+ style |= LVS_SORTASCENDING ;
3604+ control = msi_dialog_add_control ( dialog , rec , WC_LISTVIEWW , style );
3605+ if (!control )
3606+ return ERROR_FUNCTION_FAILED ;
3607+
3608+ prop = MSI_RecordGetString ( rec , 9 );
3609+ control -> property = msi_dialog_dup_property ( dialog , prop , FALSE );
3610+
3611+ control -> hImageList = ImageList_Create ( 16 , 16 , ILC_COLOR32 , 0 , 1 );
3612+ SendMessageW ( control -> hwnd , LVM_SETIMAGELIST , LVSIL_SMALL , (LPARAM )control -> hImageList );
3613+
3614+ col .mask = LVCF_FMT | LVCF_WIDTH ;
3615+ col .fmt = LVCFMT_LEFT ;
3616+ col .cx = 16 ;
3617+ SendMessageW ( control -> hwnd , LVM_INSERTCOLUMNW , 0 , (LPARAM )& col );
3618+
3619+ GetClientRect ( control -> hwnd , & rc );
3620+ col .cx = rc .right - 16 ;
3621+ SendMessageW ( control -> hwnd , LVM_INSERTCOLUMNW , 0 , (LPARAM )& col );
3622+
3623+ if (control -> property )
3624+ msi_listview_add_items ( dialog , control );
3625+
3626+ control -> handler = msi_dialog_listview_handler ;
3627+
3628+ return ERROR_SUCCESS ;
3629+ }
3630+
35253631static const struct control_handler msi_dialog_handler [] =
35263632{
35273633 { szText , msi_dialog_text_control },
@@ -3544,7 +3650,8 @@ static const struct control_handler msi_dialog_handler[] =
35443650 { szDirectoryList , msi_dialog_directory_list },
35453651 { szVolumeCostList , msi_dialog_volumecost_list },
35463652 { szVolumeSelectCombo , msi_dialog_volumeselect_combo },
3547- { szHyperLink , msi_dialog_hyperlink }
3653+ { szHyperLink , msi_dialog_hyperlink },
3654+ { szListView , msi_dialog_listview }
35483655};
35493656
35503657static UINT msi_dialog_create_controls ( MSIRECORD * rec , LPVOID param )
0 commit comments