⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialog.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
        tvhti.pt.x = (short)LOWORD( lParam );
        tvhti.pt.y = (short)HIWORD( lParam );
        tvhti.flags = 0;
        tvhti.hItem = 0;
        r = CallWindowProcW(info->oldproc, hWnd, TVM_HITTEST, 0, (LPARAM) &tvhti );
        if (tvhti.flags & TVHT_ONITEMSTATEICON)
            return msi_seltree_menu( hWnd, tvhti.hItem );
        break;
    }

    r = CallWindowProcW(info->oldproc, hWnd, msg, wParam, lParam);

    switch( msg )
    {
    case WM_NCDESTROY:
        msi_free( info );
        RemovePropW( hWnd, szButtonData );
        break;
    }
    return r;
}

static void
msi_seltree_add_child_features( MSIPACKAGE *package, HWND hwnd,
                                LPCWSTR parent, HTREEITEM hParent )
{
    struct msi_selection_tree_info *info = GetPropW( hwnd, szButtonData );
    MSIFEATURE *feature;
    TVINSERTSTRUCTW tvis;
    HTREEITEM hitem, hfirst = NULL;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if ( lstrcmpW( parent, feature->Feature_Parent ) )
            continue;

        if ( !feature->Title )
            continue;

        if ( !feature->Display )
            continue;

        memset( &tvis, 0, sizeof tvis );
        tvis.hParent = hParent;
        tvis.hInsertAfter = TVI_LAST;
        tvis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
        tvis.u.item.pszText = feature->Title;
        tvis.u.item.lParam = (LPARAM) feature;

        hitem = (HTREEITEM) SendMessageW( hwnd, TVM_INSERTITEMW, 0, (LPARAM) &tvis );
        if (!hitem)
            continue;

        if (!hfirst)
            hfirst = hitem;

        msi_seltree_sync_item_state( hwnd, feature, hitem );
        msi_seltree_add_child_features( package, hwnd,
                                        feature->Feature, hitem );

        /* the node is expanded if Display is odd */
        if ( feature->Display % 2 != 0 )
            SendMessageW( hwnd, TVM_EXPAND, TVE_EXPAND, (LPARAM) hitem );
    }

    /* select the first item */
    SendMessageW( hwnd, TVM_SELECTITEM, TVGN_CARET | TVGN_DROPHILITE, (LPARAM) hfirst );
    info->selected = hfirst;
}

static void msi_seltree_create_imagelist( HWND hwnd )
{
    const int bm_width = 32, bm_height = 16, bm_count = 3;
    const int bm_resource = 0x1001;
    HIMAGELIST himl;
    int i;
    HBITMAP hbmp;

    himl = ImageList_Create( bm_width, bm_height, FALSE, 4, 0 );
    if (!himl)
    {
        ERR("failed to create image list\n");
        return;
    }

    for (i=0; i<bm_count; i++)
    {
        hbmp = LoadBitmapW( msi_hInstance, MAKEINTRESOURCEW(i+bm_resource) );
        if (!hbmp)
        {
            ERR("failed to load bitmap %d\n", i);
            break;
        }

        /*
         * Add a dummy bitmap at offset zero because the treeview
         * can't use it as a state mask (zero means no user state).
         */
        if (!i)
            ImageList_Add( himl, hbmp, NULL );

        ImageList_Add( himl, hbmp, NULL );
    }

    SendMessageW( hwnd, TVM_SETIMAGELIST, TVSIL_STATE, (LPARAM)himl );
}

static UINT msi_dialog_seltree_handler( msi_dialog *dialog,
                                        msi_control *control, WPARAM param )
{
    struct msi_selection_tree_info *info = GetPropW( control->hwnd, szButtonData );
    LPNMTREEVIEWW tv = (LPNMTREEVIEWW)param;
    MSIRECORD *row, *rec;
    MSIFOLDER *folder;
    LPCWSTR dir;
    UINT r = ERROR_SUCCESS;

    static const WCHAR select[] = {
        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
        '`','F','e','a','t','u','r','e','`',' ','W','H','E','R','E',' ',
        '`','T','i','t','l','e','`',' ','=',' ','\'','%','s','\'',0
    };

    if (tv->hdr.code != TVN_SELCHANGINGW)
        return ERROR_SUCCESS;

    info->selected = tv->itemNew.hItem;

    row = MSI_QueryGetRecord( dialog->package->db, select, tv->itemNew.pszText );
    if (!row)
        return ERROR_FUNCTION_FAILED;

    rec = MSI_CreateRecord( 1 );

    MSI_RecordSetStringW( rec, 1, MSI_RecordGetString( row, 4 ) );
    ControlEvent_FireSubscribedEvent( dialog->package, szSelectionDescription, rec );

    dir = MSI_RecordGetString( row, 7 );
    folder = get_loaded_folder( dialog->package, dir );
    if (!folder)
    {
        r = ERROR_FUNCTION_FAILED;
        goto done;
    }

    MSI_RecordSetStringW( rec, 1, folder->ResolvedTarget );
    ControlEvent_FireSubscribedEvent( dialog->package, szSelectionPath, rec );

done:
    msiobj_release(&row->hdr);
    msiobj_release(&rec->hdr);

    return r;
}

static UINT msi_dialog_selection_tree( msi_dialog *dialog, MSIRECORD *rec )
{
    msi_control *control;
    LPCWSTR prop;
    MSIPACKAGE *package = dialog->package;
    DWORD style;
    struct msi_selection_tree_info *info;

    info = msi_alloc( sizeof *info );
    if (!info)
        return ERROR_FUNCTION_FAILED;

    /* create the treeview control */
    style = TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;
    style |= WS_GROUP | WS_VSCROLL;
    control = msi_dialog_add_control( dialog, rec, WC_TREEVIEWW, style );
    if (!control)
    {
        msi_free(info);
        return ERROR_FUNCTION_FAILED;
    }

    control->handler = msi_dialog_seltree_handler;
    control->attributes = MSI_RecordGetInteger( rec, 8 );
    prop = MSI_RecordGetString( rec, 9 );
    control->property = msi_dialog_dup_property( dialog, prop, FALSE );

    /* subclass */
    info->dialog = dialog;
    info->hwnd = control->hwnd;
    info->oldproc = (WNDPROC) SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC,
                                          (LONG_PTR)MSISelectionTree_WndProc );
    SetPropW( control->hwnd, szButtonData, info );

    ControlEvent_SubscribeToEvent( dialog->package, dialog,
                                   szSelectionPath, control->name, szProperty );

    /* initialize it */
    msi_seltree_create_imagelist( control->hwnd );
    msi_seltree_add_child_features( package, control->hwnd, NULL, NULL );

    return ERROR_SUCCESS;
}

/******************** Group Box ***************************************/

static UINT msi_dialog_group_box( msi_dialog *dialog, MSIRECORD *rec )
{
    msi_control *control;
    DWORD style;

    style = BS_GROUPBOX | WS_CHILD | WS_GROUP;
    control = msi_dialog_add_control( dialog, rec, WC_BUTTONW, style );
    if (!control)
        return ERROR_FUNCTION_FAILED;

    return ERROR_SUCCESS;
}

/******************** List Box ***************************************/

struct msi_listbox_item
{
    LPWSTR property;
    LPWSTR value;
};

struct msi_listbox_info
{
    msi_dialog *dialog;
    HWND hwnd;
    WNDPROC oldproc;
    DWORD num_items;
    struct msi_listbox_item *items;
};

static LRESULT WINAPI MSIListBox_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    struct msi_listbox_info *info;
    LRESULT r;
    DWORD j;

    TRACE("%p %04x %08x %08lx\n", hWnd, msg, wParam, lParam);

    info = GetPropW( hWnd, szButtonData );
    if (!info)
        return 0;

    r = CallWindowProcW( info->oldproc, hWnd, msg, wParam, lParam );

    switch( msg )
    {
    case WM_NCDESTROY:
        for (j = 0; j < info->num_items; j++)
        {
            msi_free( info->items[j].property );
            msi_free( info->items[j].value );
        }
        msi_free( info->items );
        msi_free( info );
        RemovePropW( hWnd, szButtonData );
        break;
    }

    return r;
}

static UINT msi_listbox_add_item( MSIRECORD *rec, LPVOID param )
{
    struct msi_listbox_info *info = param;
    struct msi_listbox_item *item;
    LPCWSTR property, value, text;
    static int index = 0;

    item = &info->items[index++];
    property = MSI_RecordGetString( rec, 1 );
    value = MSI_RecordGetString( rec, 3 );
    text = MSI_RecordGetString( rec, 4 );

    item->property = strdupW( property );
    item->value = strdupW( value );

    SendMessageW( info->hwnd, LB_ADDSTRING, 0, (LPARAM)text );

    return ERROR_SUCCESS;
}

static UINT msi_listbox_add_items( struct msi_listbox_info *info )
{
    UINT r;
    MSIQUERY *view = NULL;
    DWORD count;

    static const WCHAR query[] = {
        'S','E','L','E','C','T',' ','*',' ',
        'F','R','O','M',' ','`','L','i','s','t','B','o','x','`',' ',
        'O','R','D','E','R',' ','B','Y',' ','`','O','r','d','e','r','`',0
    };

    r = MSI_OpenQuery( info->dialog->package->db, &view, query );
    if ( r != ERROR_SUCCESS )
        return r;

    /* just get the number of records */
    r = MSI_IterateRecords( view, &count, NULL, NULL );

    info->num_items = count;
    info->items = msi_alloc( sizeof(*info->items) * count );

    r = MSI_IterateRecords( view, NULL, msi_listbox_add_item, info );
    msiobj_release( &view->hdr );

    return r;
}

static UINT msi_dialog_listbox_handler( msi_dialog *dialog,
                                        msi_control *control, WPARAM param )
{
    struct msi_listbox_info *info;
    int index;

    if( HIWORD(param) != LBN_SELCHANGE )
        return ERROR_SUCCESS;

    info = GetPropW( control->hwnd, szButtonData );
    index = SendMessageW( control->hwnd, LB_GETCURSEL, 0, 0 );

    MSI_SetPropertyW( info->dialog->package,
                      info->items[index].property, info->items[index].value );
    msi_dialog_evaluate_control_conditions( info->dialog );

    return ERROR_SUCCESS;
}

static UINT msi_dialog_list_box( msi_dialog *dialog, MSIRECORD *rec )
{
    struct msi_listbox_info *info;
    msi_control *control;
    DWORD style;

    info = msi_alloc( sizeof *info );
    if (!info)
        return ERROR_FUNCTION_FAILED;

    style = WS_TABSTOP | WS_GROUP | WS_CHILD | LBS_STANDARD;
    control = msi_dialog_add_control( dialog, rec, WC_LISTBOXW, style );
    if (!control)
        return ERROR_FUNCTION_FAILED;

    control->handler = msi_dialog_listbox_handler;

    /* subclass */
    info->dialog = dialog;
    info->hwnd = control->hwnd;
    info->items = NULL;
    info->oldproc = (WNDPROC)SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC,
                                                (LONG_PTR)MSIListBox_WndProc );
    SetPropW( control->hwnd, szButtonData, info );

    msi_listbox_add_items( info );

    return ERROR_SUCCESS;
}

/******************** Directory Combo ***************************************/

static void msi_dialog_update_directory_combo( msi_dialog *dialog, msi_control *control )
{
    LPWSTR prop, path;
    BOOL indirect;

    if (!control && !(control = msi_dialog_find_control_by_type( dialog, szDirectoryCombo )))
        return;

    indirect = control->attributes & msidbControlAttributesIndirect;
    prop = msi_dialog_dup_property( dialog, control->property, indirect );
    path = msi_dialog_dup_property( dialog, prop, TRUE );

    PathStripPathW( path );
    PathRemoveBackslashW( path );

    SendMessageW( control->hwnd, CB_INSERTSTRING, 0, (LPARAM)path );
    SendMessageW( control->hwnd, CB_SETCURSEL, 0, 0 );

    msi_free( path );
    msi_free( prop );
}

static UINT msi_dialog_directory_combo( msi_dialog *dialog, MSIRECORD *rec )
{
    msi_control *control;
    LPCWSTR prop;
    DWORD style;

    /* FIXME: use CBS_OWNERDRAWFIXED and add owner draw code */
    style = CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD |
            WS_GROUP | WS_TABSTOP | WS_VSCROLL;
    control = msi_dialog_add_control( dialog, rec, WC_COMBOBOXW, style );
    if (!control)
        return ERROR_FUNCTION_FAILED;

    control->attributes = MSI_RecordGetInteger( rec, 8 );
    prop = MSI_RecordGetString( rec, 9 );
    control->property = msi_dialog_dup_property( dialog, prop, FALSE );

    msi_dialog_update_directory_combo( dialog, control );

    return ERROR_SUCCESS;
}

/******************** Directory List ***************************************/

static void msi_dialog_update_directory_list( msi_dialog *dialog, msi_control *control )
{
    WCHAR dir_spec[MAX_PATH];
    WIN32_FIND_DATAW wfd;
    LPWSTR prop, path;
    BOOL indirect;
    LVITEMW item;
    HANDLE file;

    static const WCHAR asterisk[] = {'*',0};
    static const WCHAR dot[] = {'.',0};
    static const WCHAR dotdot[] = {'.','.',0};

    if (!control && !(control = msi_dialog_find_control_by_type( dialog, szDirectoryList )))
        return;

    /* clear the list-view */
    SendMessageW( control->hwnd, LVM_DELETEALLITEMS, 0, 0 );

    indirect = control->attributes & msidbControlAttributesIndirect;
    prop = msi_dialog_dup_property( dialog, control->property, indirect );
    path = msi_dialog_dup_property( dialog, prop, TRUE );

    lstrcpyW( dir_spec, path );
    lstrcatW( dir_spec, asterisk );

    file = FindFirstFileW( dir_spec, &wfd );
    if ( file == INVALID_HANDLE_VALUE )
        return;

    do
    {
        if ( wfd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY )
            continue;

        if ( !lstrcmpW( wfd.cFileName, dot ) || !lstrcmpW( wfd.cFileName, dotdot ) )
            continue;

        item.mask = LVIF_TEXT;
        item.cchTextMax = MAX_PATH;
        item.iItem = 0;
        item.iSubItem = 0;
        item.pszTex

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -