/*
 * Common Item Dialog
 *
 * Copyright 2010,2011 David Hedberg
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "winreg.h"
#include "shlwapi.h"

#include "commdlg.h"
#include "cdlg.h"
#include "filedlgbrowser.h"

#include "wine/debug.h"
#include "wine/list.h"

#define IDC_NAV_TOOLBAR      200
#define IDC_NAVBACK          201
#define IDC_NAVFORWARD       202

#include <initguid.h>
/* This seems to be another version of IID_IFileDialogCustomize. If
 * there is any difference I have yet to find it. */
DEFINE_GUID(IID_IFileDialogCustomizeAlt, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F);

WINE_DEFAULT_DEBUG_CHANNEL(commdlg);

static const WCHAR notifysink_childW[] = {'n','f','s','_','c','h','i','l','d',0};
static const WCHAR floatnotifysinkW[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0};

enum ITEMDLG_TYPE {
    ITEMDLG_TYPE_OPEN,
    ITEMDLG_TYPE_SAVE
};

enum ITEMDLG_CCTRL_TYPE {
    IDLG_CCTRL_MENU,
    IDLG_CCTRL_PUSHBUTTON,
    IDLG_CCTRL_COMBOBOX,
    IDLG_CCTRL_RADIOBUTTONLIST,
    IDLG_CCTRL_CHECKBUTTON,
    IDLG_CCTRL_EDITBOX,
    IDLG_CCTRL_SEPARATOR,
    IDLG_CCTRL_TEXT
};

typedef struct {
    HWND hwnd, wrapper_hwnd;
    UINT id, dlgid;
    enum ITEMDLG_CCTRL_TYPE type;
    CDCONTROLSTATEF cdcstate;
    struct list entry;
} customctrl;

typedef struct {
    struct list entry;
    IFileDialogEvents *pfde;
    DWORD cookie;
} events_client;

typedef struct FileDialogImpl {
    IFileDialog2 IFileDialog2_iface;
    union {
        IFileOpenDialog IFileOpenDialog_iface;
        IFileSaveDialog IFileSaveDialog_iface;
    } u;
    enum ITEMDLG_TYPE dlg_type;
    IExplorerBrowserEvents IExplorerBrowserEvents_iface;
    IServiceProvider       IServiceProvider_iface;
    ICommDlgBrowser3       ICommDlgBrowser3_iface;
    IOleWindow             IOleWindow_iface;
    IFileDialogCustomize   IFileDialogCustomize_iface;
    LONG ref;

    FILEOPENDIALOGOPTIONS options;
    COMDLG_FILTERSPEC *filterspecs;
    UINT filterspec_count;
    UINT filetypeindex;

    struct list events_clients;
    DWORD events_next_cookie;

    IShellItemArray *psia_selection;
    IShellItemArray *psia_results;
    IShellItem *psi_defaultfolder;
    IShellItem *psi_setfolder;
    IShellItem *psi_folder;

    HWND dlg_hwnd;
    IExplorerBrowser *peb;
    DWORD ebevents_cookie;

    LPWSTR set_filename;
    LPWSTR default_ext;
    LPWSTR custom_title;
    LPWSTR custom_okbutton;
    LPWSTR custom_cancelbutton;
    LPWSTR custom_filenamelabel;

    UINT cctrl_width, cctrl_def_height, cctrls_cols;
    HWND cctrls_hwnd;
    struct list cctrls;
    UINT_PTR cctrl_next_dlgid;

    GUID client_guid;
} FileDialogImpl;

/**************************************************************************
 * Event wrappers.
 */
static HRESULT events_OnFileOk(FileDialogImpl *This)
{
    events_client *cursor;
    HRESULT hr = S_OK;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        hr = IFileDialogEvents_OnFileOk(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
        if(FAILED(hr) && hr != E_NOTIMPL)
            break;
    }

    if(hr == E_NOTIMPL)
        hr = S_OK;

    return hr;
}

static HRESULT events_OnFolderChanging(FileDialogImpl *This, IShellItem *folder)
{
    events_client *cursor;
    HRESULT hr = S_OK;
    TRACE("%p (%p)\n", This, folder);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        hr = IFileDialogEvents_OnFolderChanging(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, folder);
        if(FAILED(hr) && hr != E_NOTIMPL)
            break;
    }

    if(hr == E_NOTIMPL)
        hr = S_OK;

    return hr;
}

static void events_OnFolderChange(FileDialogImpl *This)
{
    events_client *cursor;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        IFileDialogEvents_OnFolderChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
    }
}

static void events_OnSelectionChange(FileDialogImpl *This)
{
    events_client *cursor;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        IFileDialogEvents_OnSelectionChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
    }
}

static inline HRESULT get_cctrl_event(IFileDialogEvents *pfde, IFileDialogControlEvents **pfdce)
{
    return IFileDialogEvents_QueryInterface(pfde, &IID_IFileDialogControlEvents, (void**)pfdce);
}

static HRESULT cctrl_event_OnButtonClicked(FileDialogImpl *This, DWORD ctl_id)
{
    events_client *cursor;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        IFileDialogControlEvents *pfdce;
        if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
        {
            TRACE("Notifying %p\n", cursor);
            IFileDialogControlEvents_OnButtonClicked(pfdce, &This->IFileDialogCustomize_iface, ctl_id);
            IFileDialogControlEvents_Release(pfdce);
        }
    }

    return S_OK;
}

static HRESULT cctrl_event_OnItemSelected(FileDialogImpl *This, DWORD ctl_id, DWORD item_id)
{
    events_client *cursor;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        IFileDialogControlEvents *pfdce;
        if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
        {
            TRACE("Notifying %p\n", cursor);
            IFileDialogControlEvents_OnItemSelected(pfdce, &This->IFileDialogCustomize_iface, ctl_id, item_id);
            IFileDialogControlEvents_Release(pfdce);
        }
    }

    return S_OK;
}

static HRESULT cctrl_event_OnCheckButtonToggled(FileDialogImpl *This, DWORD ctl_id, BOOL checked)
{
    events_client *cursor;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        IFileDialogControlEvents *pfdce;
        if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
        {
            TRACE("Notifying %p\n", cursor);
            IFileDialogControlEvents_OnCheckButtonToggled(pfdce, &This->IFileDialogCustomize_iface, ctl_id, checked);
            IFileDialogControlEvents_Release(pfdce);
        }
    }

    return S_OK;
}

static HRESULT cctrl_event_OnControlActivating(FileDialogImpl *This,
                                                  DWORD ctl_id)
{
    events_client *cursor;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
    {
        IFileDialogControlEvents *pfdce;
        if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
        {
            TRACE("Notifying %p\n", cursor);
            IFileDialogControlEvents_OnControlActivating(pfdce, &This->IFileDialogCustomize_iface, ctl_id);
            IFileDialogControlEvents_Release(pfdce);
        }
    }

    return S_OK;
}

/**************************************************************************
 * Helper functions.
 */
static UINT get_file_name(FileDialogImpl *This, LPWSTR *str)
{
    HWND hwnd_edit = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
    UINT len;

    if(!hwnd_edit)
    {
        if(This->set_filename)
        {
            len = lstrlenW(This->set_filename);
            *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
            lstrcpyW(*str, This->set_filename);
            return len;
        }
        return FALSE;
    }

    len = SendMessageW(hwnd_edit, WM_GETTEXTLENGTH, 0, 0);
    *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
    if(!*str)
        return FALSE;

    SendMessageW(hwnd_edit, WM_GETTEXT, len+1, (LPARAM)*str);
    return len;
}

static BOOL set_file_name(FileDialogImpl *This, LPCWSTR str)
{
    HWND hwnd_edit = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);

    if(This->set_filename)
        LocalFree(This->set_filename);

    This->set_filename = StrDupW(str);

    return SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str);
}

static void fill_filename_from_selection(FileDialogImpl *This)
{
    IShellItem *psi;
    LPWSTR *names;
    HRESULT hr;
    UINT item_count, valid_count;
    UINT len_total, i;

    if(!This->psia_selection)
        return;

    hr = IShellItemArray_GetCount(This->psia_selection, &item_count);
    if(FAILED(hr) || !item_count)
        return;

    names = HeapAlloc(GetProcessHeap(), 0, item_count*sizeof(LPWSTR));

    /* Get names of the selected items */
    valid_count = 0; len_total = 0;
    for(i = 0; i < item_count; i++)
    {
        hr = IShellItemArray_GetItemAt(This->psia_selection, i, &psi);
        if(SUCCEEDED(hr))
        {
            UINT attr;

            hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER, &attr);
            if(SUCCEEDED(hr) && (attr & SFGAO_FOLDER))
                continue; /* FIXME: FOS_PICKFOLDERS */

            hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &names[valid_count]);
            if(SUCCEEDED(hr))
            {
                len_total += lstrlenW(names[valid_count]) + 3;
                valid_count++;
            }
            IShellItem_Release(psi);
        }
    }

    if(valid_count == 1)
    {
        set_file_name(This, names[0]);
        CoTaskMemFree(names[0]);
    }
    else if(valid_count > 1)
    {
        LPWSTR string = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len_total);
        LPWSTR cur_point = string;

        for(i = 0; i < valid_count; i++)
        {
            LPWSTR file = names[i];
            *cur_point++ = '\"';
            lstrcpyW(cur_point, file);
            cur_point += lstrlenW(file);
            *cur_point++ = '\"';
            *cur_point++ = ' ';
            CoTaskMemFree(file);
        }
        *(cur_point-1) = '\0';

        set_file_name(This, string);
        HeapFree(GetProcessHeap(), 0, string);
    }

    HeapFree(GetProcessHeap(), 0, names);
    return;
}

static LPWSTR get_first_ext_from_spec(LPWSTR buf, LPCWSTR spec)
{
    WCHAR *endpos, *ext;

    lstrcpyW(buf, spec);
    if( (endpos = StrChrW(buf, ';')) )
        *endpos = '\0';

    ext = PathFindExtensionW(buf);
    if(StrChrW(ext, '*'))
        return NULL;

    return ext;
}

static HRESULT on_default_action(FileDialogImpl *This)
{
    IShellFolder *psf_parent, *psf_desktop;
    LPITEMIDLIST *pidla;
    LPITEMIDLIST current_folder;
    LPWSTR fn_iter, files = NULL, tmp_files;
    UINT file_count = 0, len, i;
    int open_action;
    HRESULT hr, ret = E_FAIL;

    len = get_file_name(This, &tmp_files);
    if(len)
    {
        UINT size_used;
        file_count = COMDLG32_SplitFileNames(tmp_files, len, &files, &size_used);
        CoTaskMemFree(tmp_files);
    }
    if(!file_count) return E_FAIL;

    hr = SHGetIDListFromObject((IUnknown*)This->psi_folder, &current_folder);
    if(FAILED(hr))
    {
        ERR("Failed to get pidl for current directory.\n");
        HeapFree(GetProcessHeap(), 0, files);
        return hr;
    }

    TRACE("Acting on %d file(s).\n", file_count);

    pidla = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * file_count);
    open_action = ONOPEN_OPEN;
    fn_iter = files;

    for(i = 0; i < file_count && open_action == ONOPEN_OPEN; i++)
    {
        WCHAR canon_filename[MAX_PATH];
        psf_parent = NULL;

        COMDLG32_GetCanonicalPath(current_folder, fn_iter, canon_filename);

        if( (This->options & FOS_NOVALIDATE) &&
            !(This->options & FOS_FILEMUSTEXIST) )
            open_action = ONOPEN_OPEN;
        else
            open_action = ONOPEN_BROWSE;

        open_action = FILEDLG95_ValidatePathAction(canon_filename, &psf_parent, This->dlg_hwnd,
                                                   This->options & ~FOS_FILEMUSTEXIST,
                                                   (This->dlg_type == ITEMDLG_TYPE_SAVE),
                                                   open_action);

        /* Add the proper extension */
        if(open_action == ONOPEN_OPEN)
        {
            static const WCHAR dotW[] = {'.',0};

            if(This->dlg_type == ITEMDLG_TYPE_SAVE)
            {
                WCHAR extbuf[MAX_PATH], *newext = NULL;

                if(This->filterspec_count)
                {
                    newext = get_first_ext_from_spec(extbuf, This->filterspecs[This->filetypeindex].pszSpec);
                }
                else if(This->default_ext)
                {
                    lstrcpyW(extbuf, dotW);
                    lstrcatW(extbuf, This->default_ext);
                    newext = extbuf;
                }

                if(newext)
                {
                    WCHAR *ext = PathFindExtensionW(canon_filename);
                    if(lstrcmpW(ext, newext))
                        lstrcatW(canon_filename, newext);
                }
            }
            else
            {
                if( !(This->options & FOS_NOVALIDATE) && (This->options & FOS_FILEMUSTEXIST) &&
                    !PathFileExistsW(canon_filename))
                {
                    if(This->default_ext)
                    {
                        lstrcatW(canon_filename, dotW);
                        lstrcatW(canon_filename, This->default_ext);

                        if(!PathFileExistsW(canon_filename))
                        {
                            FILEDLG95_OnOpenMessage(This->dlg_hwnd, 0, IDS_FILENOTEXISTING);
                            open_action = ONOPEN_BROWSE;
                        }
                    }
                    else
                    {
                        FILEDLG95_OnOpenMessage(This->dlg_hwnd, 0, IDS_FILENOTEXISTING);
                        open_action = ONOPEN_BROWSE;
                    }
                }
            }
        }

        pidla[i] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename);

        if(psf_parent && !(open_action == ONOPEN_BROWSE))
            IShellFolder_Release(psf_parent);

        fn_iter += (WCHAR)lstrlenW(fn_iter) + 1;
    }

    HeapFree(GetProcessHeap(), 0, files);
    ILFree(current_folder);

    if((This->options & FOS_PICKFOLDERS) && open_action == ONOPEN_BROWSE)
        open_action = ONOPEN_OPEN; /* FIXME: Multiple folders? */

    switch(open_action)
    {
    case ONOPEN_SEARCH:
        FIXME("Filtering not implemented.\n");
        break;

    case ONOPEN_BROWSE:
        hr = IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psf_parent, SBSP_DEFBROWSER);
        if(FAILED(hr))
            ERR("Failed to browse to directory: %08x\n", hr);

        IShellFolder_Release(psf_parent);
        break;

    case ONOPEN_OPEN:
        if(events_OnFileOk(This) != S_OK)
            break;

        hr = SHGetDesktopFolder(&psf_desktop);
        if(SUCCEEDED(hr))
        {
            if(This->psia_results)
                IShellItemArray_Release(This->psia_results);

            hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
                                        &This->psia_results);
            if(SUCCEEDED(hr))
                ret = S_OK;

            IShellFolder_Release(psf_desktop);
        }
        break;

    default:
        ERR("Failed.\n");
        break;
    }

    /* Clean up */
    for(i = 0; i < file_count; i++)
        ILFree(pidla[i]);
    HeapFree(GetProcessHeap(), 0, pidla);

    /* Success closes the dialog */
    return ret;
}

/**************************************************************************
 * Control functions.
 */
static inline customctrl *get_cctrl_from_dlgid(FileDialogImpl *This, DWORD dlgid)
{
    customctrl *ctrl;

    LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
        if(ctrl->dlgid == dlgid)
            return ctrl;

    ERR("Failed to find control with dialog id %d\n", dlgid);
    return NULL;
}

static inline customctrl *get_cctrl(FileDialogImpl *This, DWORD ctlid)
{
    customctrl *ctrl;

    LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
        if(ctrl->id == ctlid)
            return ctrl;

    ERR("Failed to find control with control id %d\n", ctlid);
    return NULL;
}

static void ctrl_resize(HWND hctrl, UINT min_width, UINT max_width, BOOL multiline)
{
    LPWSTR text;
    UINT len, final_width;
    UINT lines, final_height;
    SIZE size;
    RECT rc;
    HDC hdc;
    WCHAR *c;

    TRACE("\n");

    len = SendMessageW(hctrl, WM_GETTEXTLENGTH, 0, 0);
    text = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
    if(!text) return;
    SendMessageW(hctrl, WM_GETTEXT, len+1, (LPARAM)text);

    hdc = GetDC(hctrl);
    GetTextExtentPoint32W(hdc, text, lstrlenW(text), &size);
    ReleaseDC(hctrl, hdc);

    if(len && multiline)
    {
        /* FIXME: line-wrap */
        for(lines = 1, c = text; *c != '\0'; c++)
            if(*c == '\n') lines++;

        final_height = size.cy*lines + 2*4;
    }
    else
    {
        GetWindowRect(hctrl, &rc);
        final_height = rc.bottom - rc.top;
    }

    final_width = min(max(size.cx, min_width) + 4, max_width);
    SetWindowPos(hctrl, NULL, 0, 0, final_width, final_height,
                 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);

    HeapFree(GetProcessHeap(), 0, text);
}

static void customctrl_resize(FileDialogImpl *This, customctrl *ctrl)
{
    RECT rc;

    switch(ctrl->type)
    {
    case IDLG_CCTRL_PUSHBUTTON:
    case IDLG_CCTRL_COMBOBOX:
    case IDLG_CCTRL_CHECKBUTTON:
    case IDLG_CCTRL_TEXT:
        ctrl_resize(ctrl->hwnd, 160, 160, TRUE);
        GetWindowRect(ctrl->hwnd, &rc);
        SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
                     SWP_NOZORDER|SWP_NOMOVE|SWP_NOZORDER);
        break;
    case IDLG_CCTRL_RADIOBUTTONLIST:
    case IDLG_CCTRL_EDITBOX:
    case IDLG_CCTRL_SEPARATOR:
    case IDLG_CCTRL_MENU:
        /* Nothing */
        break;
    }
}

static LRESULT notifysink_on_create(HWND hwnd, CREATESTRUCTW *crs)
{
    FileDialogImpl *This = crs->lpCreateParams;
    TRACE("%p\n", This);

    SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
    return TRUE;
}

static LRESULT notifysink_on_bn_clicked(FileDialogImpl *This, HWND hwnd, WPARAM wparam)
{
    customctrl *ctrl = get_cctrl_from_dlgid(This, LOWORD(wparam));

    TRACE("%p, %lx\n", This, wparam);

    if(ctrl)
    {
        if(ctrl->type == IDLG_CCTRL_CHECKBUTTON)
        {
            BOOL checked = (SendMessageW(ctrl->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED);
            cctrl_event_OnCheckButtonToggled(This, ctrl->id, checked);
        }
        else
            cctrl_event_OnButtonClicked(This, ctrl->id);
    }

    return TRUE;
}

static LRESULT notifysink_on_cbn_selchange(FileDialogImpl *This, HWND hwnd, WPARAM wparam)
{
    customctrl *ctrl = get_cctrl_from_dlgid(This, LOWORD(wparam));
    TRACE("%p, %p (%lx)\n", This, ctrl, wparam);

    if(ctrl)
    {
        UINT index = SendMessageW(ctrl->hwnd, CB_GETCURSEL, 0, 0);
        UINT selid = SendMessageW(ctrl->hwnd, CB_GETITEMDATA, index, 0);

        cctrl_event_OnItemSelected(This, ctrl->id, selid);
    }
    return TRUE;
}

static LRESULT notifysink_on_tvn_dropdown(FileDialogImpl *This, LPARAM lparam)
{
    NMTOOLBARW *nmtb = (NMTOOLBARW*)lparam;
    customctrl *ctrl = get_cctrl_from_dlgid(This, GetDlgCtrlID(nmtb->hdr.hwndFrom));
    POINT pt = { 0, nmtb->rcButton.bottom };
    TBBUTTON tbb;
    UINT idcmd;

    TRACE("%p, %p (%lx)\n", This, ctrl, lparam);

    if(ctrl)
    {
        cctrl_event_OnControlActivating(This,ctrl->id);

        SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
        ClientToScreen(ctrl->hwnd, &pt);
        idcmd = TrackPopupMenu((HMENU)tbb.dwData, TPM_RETURNCMD, pt.x, pt.y, 0, This->dlg_hwnd, NULL);
        if(idcmd)
            cctrl_event_OnItemSelected(This, ctrl->id, idcmd);
    }

    return TBDDRET_DEFAULT;
}

static LRESULT notifysink_on_wm_command(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam)
{
    switch(HIWORD(wparam))
    {
    case BN_CLICKED:          return notifysink_on_bn_clicked(This, hwnd, wparam);
    case CBN_SELCHANGE:       return notifysink_on_cbn_selchange(This, hwnd, wparam);
    }

    return FALSE;
}

static LRESULT notifysink_on_wm_notify(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam)
{
    NMHDR *nmhdr = (NMHDR*)lparam;

    switch(nmhdr->code)
    {
    case TBN_DROPDOWN:        return notifysink_on_tvn_dropdown(This, lparam);
    }

    return FALSE;
}

static LRESULT CALLBACK notifysink_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
    HWND hwnd_child;
    RECT rc;

    switch(message)
    {
    case WM_NCCREATE:         return notifysink_on_create(hwnd, (CREATESTRUCTW*)lparam);
    case WM_COMMAND:          return notifysink_on_wm_command(This, hwnd, wparam, lparam);
    case WM_NOTIFY:           return notifysink_on_wm_notify(This, hwnd, wparam, lparam);
    case WM_SIZE:
        hwnd_child = GetPropW(hwnd, notifysink_childW);
        GetClientRect(hwnd, &rc);
        SetWindowPos(hwnd_child, NULL, 0, 0, rc.right, rc.bottom, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
        return TRUE;
    }

    return DefWindowProcW(hwnd, message, wparam, lparam);
}

static HRESULT cctrl_create_new(FileDialogImpl *This, DWORD id,
                                LPCWSTR text, LPCWSTR wndclass, DWORD ctrl_wsflags,
                                DWORD ctrl_exflags, UINT height, customctrl **ppctrl)
{
    HWND ns_hwnd, control_hwnd;
    DWORD wsflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    customctrl *ctrl;

    if(get_cctrl(This, id))
        return E_UNEXPECTED; /* Duplicate id */

    ns_hwnd = CreateWindowExW(0, floatnotifysinkW, NULL, wsflags,
                              0, 0, This->cctrl_width, height, This->cctrls_hwnd,
                              (HMENU)This->cctrl_next_dlgid, COMDLG32_hInstance, This);
    control_hwnd = CreateWindowExW(ctrl_exflags, wndclass, text, wsflags | ctrl_wsflags,
                                   0, 0, This->cctrl_width, height, ns_hwnd,
                                   (HMENU)This->cctrl_next_dlgid, COMDLG32_hInstance, 0);

    if(!ns_hwnd || !control_hwnd)
    {
        ERR("Failed to create wrapper (%p) or control (%p)\n", ns_hwnd, control_hwnd);
        DestroyWindow(ns_hwnd);
        DestroyWindow(control_hwnd);

        return E_FAIL;
    }

    SetPropW(ns_hwnd, notifysink_childW, control_hwnd);

    ctrl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(customctrl));
    if(!ctrl)
        return E_OUTOFMEMORY;

    ctrl->hwnd = control_hwnd;
    ctrl->wrapper_hwnd = ns_hwnd;
    ctrl->id = id;
    ctrl->dlgid = This->cctrl_next_dlgid;
    ctrl->cdcstate = CDCS_ENABLED | CDCS_VISIBLE;
    list_add_tail(&This->cctrls, &ctrl->entry);
    if(ppctrl) *ppctrl = ctrl;

    This->cctrl_next_dlgid++;
    return S_OK;
}

/**************************************************************************
 * Container functions.
 */
static UINT ctrl_container_resize(FileDialogImpl *This, UINT container_width)
{
    UINT container_height;
    UINT column_width;
    UINT nr_of_cols;
    UINT max_control_height, total_height = 0;
    UINT cur_col_pos, cur_row_pos;
    customctrl *ctrl;
    BOOL fits_height;
    static const UINT col_indent = 100; /* The first column is indented 100px */
    static const UINT cspacing = 90;    /* Columns are spaced with 90px */
    static const UINT rspacing = 4;     /* Rows are spaced with 4 px. */

    /* Given the new width of the container, this function determines the
     * needed height of the container and places the controls according to
     * the new layout. Returns the new height.
     */

    TRACE("%p\n", This);

    column_width = This->cctrl_width + cspacing;
    nr_of_cols = (container_width - col_indent + cspacing) / column_width;

    /* We don't need to do anything unless the number of visible columns has changed. */
    if(nr_of_cols == This->cctrls_cols)
    {
        RECT rc;
        GetWindowRect(This->cctrls_hwnd, &rc);
        return rc.bottom - rc.top;
    }

   This->cctrls_cols = nr_of_cols;

    /* Get the size of the tallest control, and the total size of
     * all the controls to figure out the number of slots we need.
     */
    max_control_height = 0;
    LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
    {
        if(ctrl->cdcstate & CDCS_VISIBLE)
        {
            RECT rc;
            UINT control_height;
            GetWindowRect(ctrl->wrapper_hwnd, &rc);
            control_height = rc.bottom - rc.top;
            max_control_height = max(max_control_height, control_height);

            total_height +=  control_height + rspacing;
        }
    }

    if(!total_height)
        return 0;

    container_height = max(total_height / nr_of_cols, max_control_height + rspacing);
    TRACE("Guess: container_height: %d\n",container_height);

    /* Incrementally increase container_height until all the controls
     * fit.
     */
    do {
        UINT columns_needed = 1;
        cur_row_pos = 0;

        fits_height = TRUE;
        LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
        {
            if(ctrl->cdcstate & CDCS_VISIBLE)
            {
                RECT rc;
                UINT control_height;
                GetWindowRect(ctrl->wrapper_hwnd, &rc);
                control_height = rc.bottom - rc.top;

                if(cur_row_pos + control_height > container_height)
                {
                    if(++columns_needed > nr_of_cols)
                    {
                        container_height += 1;
                        fits_height = FALSE;
                        break;
                    }
                    cur_row_pos = 0;
                }

                cur_row_pos += control_height + rspacing;
            }
        }
    } while(!fits_height);

    TRACE("Final container height: %d\n", container_height);

    /* Move the controls to their final destination
     */
    cur_col_pos = col_indent, cur_row_pos = 0;
    LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
    {
        if(ctrl->cdcstate & CDCS_VISIBLE)
        {
            RECT rc;
            UINT control_height;
            GetWindowRect(ctrl->wrapper_hwnd, &rc);
            control_height = rc.bottom - rc.top;

            if(cur_row_pos + control_height > container_height)
            {
                cur_row_pos = 0;
                cur_col_pos += This->cctrl_width + cspacing;
            }

            SetWindowPos(ctrl->wrapper_hwnd, NULL, cur_col_pos, cur_row_pos, 0, 0,
                         SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);

            cur_row_pos += control_height + rspacing;
        }
    }

    /* Sanity check */
    if(cur_row_pos + This->cctrl_width > container_width)
        ERR("-- Failed to place controls properly.\n");

    return container_height;
}

static void ctrl_container_reparent(FileDialogImpl *This, HWND parent)
{
    LONG wndstyle;

    if(parent)
    {
        customctrl *ctrl;
        HFONT font;

        wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
        wndstyle &= ~(WS_POPUP);
        wndstyle |= WS_CHILD;
        SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle);

        SetParent(This->cctrls_hwnd, parent);
        ShowWindow(This->cctrls_hwnd, TRUE);

        /* Set the fonts to match the dialog font. */
        font = (HFONT)SendMessageW(parent, WM_GETFONT, 0, 0);
        if(!font)
            ERR("Failed to get font handle from dialog.\n");

        LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
        {
            if(font) SendMessageW(ctrl->hwnd, WM_SETFONT, (WPARAM)font, TRUE);
            customctrl_resize(This, ctrl);
        }
    }
    else
    {
        ShowWindow(This->cctrls_hwnd, FALSE);

        wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
        wndstyle &= ~(WS_CHILD);
        wndstyle |= WS_POPUP;
        SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle);

        SetParent(This->cctrls_hwnd, NULL);
    }
}

static LRESULT ctrl_container_on_create(HWND hwnd, CREATESTRUCTW *crs)
{
    FileDialogImpl *This = crs->lpCreateParams;
    TRACE("%p\n", This);

    SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
    return TRUE;
}

static LRESULT ctrl_container_on_wm_destroy(FileDialogImpl *This)
{
    customctrl *cur1, *cur2;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY_SAFE(cur1, cur2, &This->cctrls, customctrl, entry)
    {
        TRACE("Freeing control %p\n", cur1);
        list_remove(&cur1->entry);

        if(cur1->type == IDLG_CCTRL_MENU)
        {
            TBBUTTON tbb;
            SendMessageW(cur1->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
            DestroyMenu((HMENU)tbb.dwData);
        }

        DestroyWindow(cur1->hwnd);
        HeapFree(GetProcessHeap(), 0, cur1);
    }

    return TRUE;
}

static LRESULT CALLBACK ctrl_container_wndproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
    FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);

    switch(umessage)
    {
    case WM_NCCREATE:         return ctrl_container_on_create(hwnd, (CREATESTRUCTW*)lparam);
    case WM_DESTROY:          return ctrl_container_on_wm_destroy(This);
    default:                  return DefWindowProcW(hwnd, umessage, wparam, lparam);
    }

    return FALSE;
}

static HRESULT init_custom_controls(FileDialogImpl *This)
{
    WNDCLASSW wc;
    static const WCHAR ctrl_container_classname[] =
        {'i','d','l','g','_','c','o','n','t','a','i','n','e','r','_','p','a','n','e',0};

    InitCommonControlsEx(NULL);

    This->cctrl_width = 160;      /* Controls have a fixed width */
    This->cctrl_def_height = 23;
    This->cctrls_cols = 0;

    This->cctrl_next_dlgid = 0x2000;
    list_init(&This->cctrls);

    if( !GetClassInfoW(COMDLG32_hInstance, ctrl_container_classname, &wc) )
    {
        wc.style            = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc      = ctrl_container_wndproc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = COMDLG32_hInstance;
        wc.hIcon            = 0;
        wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_ARROW);
        wc.hbrBackground    = (HBRUSH)(COLOR_BTNFACE + 1);
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = ctrl_container_classname;

        if(!RegisterClassW(&wc)) return E_FAIL;
    }

    This->cctrls_hwnd = CreateWindowExW(0, ctrl_container_classname, NULL,
                                        WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                                        0, 0, 0, 0, NULL, 0,
                                        COMDLG32_hInstance, (void*)This);
    if(!This->cctrls_hwnd)
        return E_FAIL;

    SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, WS_TABSTOP);

    /* Register class for  */
    if( !GetClassInfoW(COMDLG32_hInstance, floatnotifysinkW, &wc) ||
        wc.hInstance != COMDLG32_hInstance)
    {
        wc.style            = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc      = notifysink_proc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = COMDLG32_hInstance;
        wc.hIcon            = 0;
        wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_ARROW);
        wc.hbrBackground    = (HBRUSH)(COLOR_BTNFACE + 1);
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = floatnotifysinkW;

        if (!RegisterClassW(&wc))
            ERR("Failed to register FloatNotifySink window class.\n");
    }

    return S_OK;
}

/**************************************************************************
 * Window related functions.
 */
static SIZE update_layout(FileDialogImpl *This)
{
    HDWP hdwp;
    HWND hwnd;
    RECT dialog_rc;
    RECT cancel_rc, open_rc;
    RECT filetype_rc, filename_rc, filenamelabel_rc;
    RECT toolbar_rc, ebrowser_rc, customctrls_rc;
    int missing_width, missing_height;
    static const UINT vspacing = 4, hspacing = 4;
    SIZE ret;

    GetClientRect(This->dlg_hwnd, &dialog_rc);

    missing_width = max(0, 320 - dialog_rc.right);
    missing_height = max(0, 200 - dialog_rc.bottom);

    if(missing_width || missing_height)
    {
        TRACE("Missing (%d, %d)\n", missing_width, missing_height);
        ret.cx = missing_width;
        ret.cy = missing_height;
        return ret;
    }

    /****
     * Calculate the size of the dialog and all the parts.
     */

    /* Cancel button */
    hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL);
    if(hwnd)
    {
        int cancel_width, cancel_height;
        GetWindowRect(hwnd, &cancel_rc);
        cancel_width = cancel_rc.right - cancel_rc.left;
        cancel_height = cancel_rc.bottom - cancel_rc.top;

        cancel_rc.left = dialog_rc.right - cancel_width - hspacing;
        cancel_rc.top = dialog_rc.bottom - cancel_height - vspacing;
        cancel_rc.right = cancel_rc.left + cancel_width;
        cancel_rc.bottom = cancel_rc.top + cancel_height;
    }

    /* Open/Save button */
    hwnd = GetDlgItem(This->dlg_hwnd, IDOK);
    if(hwnd)
    {
        int open_width, open_height;
        GetWindowRect(hwnd, &open_rc);
        open_width = open_rc.right - open_rc.left;
        open_height = open_rc.bottom - open_rc.top;

        open_rc.left = cancel_rc.left - open_width - hspacing;
        open_rc.top = cancel_rc.top;
        open_rc.right = open_rc.left + open_width;
        open_rc.bottom = open_rc.top + open_height;
    }

    /* The filetype combobox. */
    hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
    if(hwnd)
    {
        int filetype_width, filetype_height;
        GetWindowRect(hwnd, &filetype_rc);

        filetype_width = filetype_rc.right - filetype_rc.left;
        filetype_height = filetype_rc.bottom - filetype_rc.top;

        filetype_rc.right = cancel_rc.right;

        filetype_rc.left = filetype_rc.right - filetype_width;
        filetype_rc.top = cancel_rc.top - filetype_height - vspacing;
        filetype_rc.bottom = filetype_rc.top + filetype_height;

        if(!This->filterspec_count)
            filetype_rc.left = filetype_rc.right;
    }

    /* Filename label. */
    hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC);
    if(hwnd)
    {
        int filetypelabel_width, filetypelabel_height;
        GetWindowRect(hwnd, &filenamelabel_rc);

        filetypelabel_width = filenamelabel_rc.right - filenamelabel_rc.left;
        filetypelabel_height = filenamelabel_rc.bottom - filenamelabel_rc.top;

        filenamelabel_rc.left = 160; /* FIXME */
        filenamelabel_rc.top = filetype_rc.top;
        filenamelabel_rc.right = filenamelabel_rc.left + filetypelabel_width;
        filenamelabel_rc.bottom = filenamelabel_rc.top + filetypelabel_height;
    }

    /* Filename edit box. */
    hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
    if(hwnd)
    {
        int filename_width, filename_height;
        GetWindowRect(hwnd, &filename_rc);

        filename_width = filetype_rc.left - filenamelabel_rc.right - hspacing*2;
        filename_height = filename_rc.bottom - filename_rc.top;

        filename_rc.left = filenamelabel_rc.right + hspacing;
        filename_rc.top = filetype_rc.top;
        filename_rc.right = filename_rc.left + filename_width;
        filename_rc.bottom = filename_rc.top + filename_height;
    }

    hwnd = GetDlgItem(This->dlg_hwnd, IDC_NAV_TOOLBAR);
    if(hwnd)
    {
        GetWindowRect(hwnd, &toolbar_rc);
        MapWindowPoints(NULL, This->dlg_hwnd, (POINT*)&toolbar_rc, 2);
    }

    /* The custom controls */
    customctrls_rc.left = dialog_rc.left + hspacing;
    customctrls_rc.right = dialog_rc.right - hspacing;
    customctrls_rc.bottom = filename_rc.top - vspacing;
    customctrls_rc.top = customctrls_rc.bottom -
        ctrl_container_resize(This, customctrls_rc.right - customctrls_rc.left);

    /* The ExplorerBrowser control. */
    ebrowser_rc.left = dialog_rc.left + hspacing;
    ebrowser_rc.top = toolbar_rc.bottom + vspacing;
    ebrowser_rc.right = dialog_rc.right - hspacing;
    ebrowser_rc.bottom = customctrls_rc.top - vspacing;

    /****
     * Move everything to the right place.
     */

    /* FIXME: The Save Dialog uses a slightly different layout. */
    hdwp = BeginDeferWindowPos(7);

    if(hdwp && This->peb)
        IExplorerBrowser_SetRect(This->peb, &hdwp, ebrowser_rc);

    if(hdwp && This->cctrls_hwnd)
        DeferWindowPos(hdwp, This->cctrls_hwnd, NULL,
                       customctrls_rc.left, customctrls_rc.top,
                       customctrls_rc.right - customctrls_rc.left, customctrls_rc.bottom - customctrls_rc.top,
                       SWP_NOZORDER | SWP_NOACTIVATE);

    /* The default controls */
    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) )
        DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0,
                       SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);

    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
        DeferWindowPos(hdwp, hwnd, NULL, filename_rc.left, filename_rc.top,
                       filename_rc.right - filename_rc.left, filename_rc.bottom - filename_rc.top,
                       SWP_NOZORDER | SWP_NOACTIVATE);

    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)) )
        DeferWindowPos(hdwp, hwnd, NULL, filenamelabel_rc.left, filenamelabel_rc.top, 0, 0,
                       SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);

    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDOK)) )
        DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_rc.top, 0, 0,
                       SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);

    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL)) )
        DeferWindowPos(hdwp, hwnd, NULL, cancel_rc.left, cancel_rc.top, 0, 0,
                       SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);

    if(hdwp)
        EndDeferWindowPos(hdwp);
    else
        ERR("Failed to position dialog controls.\n");

    ret.cx = 0; ret.cy = 0;
    return ret;
}

static HRESULT init_explorerbrowser(FileDialogImpl *This)
{
    IShellItem *psi_folder;
    FOLDERSETTINGS fos;
    RECT rc = {0};
    HRESULT hr;

    /* Create ExplorerBrowser instance */
    OleInitialize(NULL);

    hr = CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IExplorerBrowser, (void**)&This->peb);
    if(FAILED(hr))
    {
        ERR("Failed to instantiate ExplorerBrowser control.\n");
        return hr;
    }

    IExplorerBrowser_SetOptions(This->peb, EBO_SHOWFRAMES);

    hr = IExplorerBrowser_Initialize(This->peb, This->dlg_hwnd, &rc, NULL);
    if(FAILED(hr))
    {
        ERR("Failed to initialize the ExplorerBrowser control.\n");
        IExplorerBrowser_Release(This->peb);
        This->peb = NULL;
        return hr;
    }
    hr = IExplorerBrowser_Advise(This->peb, &This->IExplorerBrowserEvents_iface, &This->ebevents_cookie);
    if(FAILED(hr))
        ERR("Advise (ExplorerBrowser) failed.\n");

    /* Get previous options? */
    fos.ViewMode = fos.fFlags = 0;
    if(!(This->options & FOS_ALLOWMULTISELECT))
        fos.fFlags |= FWF_SINGLESEL;

    IExplorerBrowser_SetFolderSettings(This->peb, &fos);

    hr = IUnknown_SetSite((IUnknown*)This->peb, (IUnknown*)This);
    if(FAILED(hr))
        ERR("SetSite (ExplorerBrowser) failed.\n");

    /* Browse somewhere */
    psi_folder = This->psi_setfolder ? This->psi_setfolder : This->psi_defaultfolder;
    IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psi_folder, SBSP_DEFBROWSER);

    return S_OK;
}

static void init_toolbar(FileDialogImpl *This, HWND hwnd)
{
    HWND htoolbar;
    TBADDBITMAP tbab;
    TBBUTTON button[2];

    htoolbar = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE,
                               0, 0, 0, 0,
                               hwnd, (HMENU)IDC_NAV_TOOLBAR, NULL, NULL);

    tbab.hInst = HINST_COMMCTRL;
    tbab.nID = IDB_HIST_LARGE_COLOR;
    SendMessageW(htoolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);

    button[0].iBitmap = HIST_BACK;
    button[0].idCommand = IDC_NAVBACK;
    button[0].fsState = TBSTATE_ENABLED;
    button[0].fsStyle = BTNS_BUTTON;
    button[0].dwData = 0;
    button[0].iString = 0;

    button[1].iBitmap = HIST_FORWARD;
    button[1].idCommand = IDC_NAVFORWARD;
    button[1].fsState = TBSTATE_ENABLED;
    button[1].fsStyle = BTNS_BUTTON;
    button[1].dwData = 0;
    button[1].iString = 0;

    SendMessageW(htoolbar, TB_ADDBUTTONSW, 2, (LPARAM)button);
    SendMessageW(htoolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(24,24));
    SendMessageW(htoolbar, TB_AUTOSIZE, 0, 0);
}

static void update_control_text(FileDialogImpl *This)
{
    HWND hitem;
    if(This->custom_title)
        SetWindowTextW(This->dlg_hwnd, This->custom_title);

    if(This->custom_okbutton &&
       (hitem = GetDlgItem(This->dlg_hwnd, IDOK)))
    {
        SetWindowTextW(hitem, This->custom_okbutton);
        ctrl_resize(hitem, 50, 250, FALSE);
    }

    if(This->custom_cancelbutton &&
       (hitem = GetDlgItem(This->dlg_hwnd, IDCANCEL)))
    {
        SetWindowTextW(hitem, This->custom_cancelbutton);
        ctrl_resize(hitem, 50, 250, FALSE);
    }

    if(This->custom_filenamelabel &&
       (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)))
    {
        SetWindowTextW(hitem, This->custom_filenamelabel);
        ctrl_resize(hitem, 50, 250, FALSE);
    }
}

static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam)
{
    FileDialogImpl *This = (FileDialogImpl*)lParam;
    HWND hitem;

    TRACE("(%p, %p)\n", This, hwnd);

    SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
    This->dlg_hwnd = hwnd;

    hitem = GetDlgItem(This->dlg_hwnd, pshHelp);
    if(hitem) ShowWindow(hitem, SW_HIDE);

    hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPESTATIC);
    if(hitem) ShowWindow(hitem, SW_HIDE);

    /* Fill filetypes combobox, or hide it. */
    hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
    if(This->filterspec_count)
    {
        UINT i;
        for(i = 0; i < This->filterspec_count; i++)
            SendMessageW(hitem, CB_ADDSTRING, 0, (LPARAM)This->filterspecs[i].pszName);

        SendMessageW(hitem, CB_SETCURSEL, This->filetypeindex, 0);
    }
    else
        ShowWindow(hitem, SW_HIDE);

    if(This->set_filename &&
       (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
        SendMessageW(hitem, WM_SETTEXT, 0, (LPARAM)This->set_filename);

    ctrl_container_reparent(This, This->dlg_hwnd);
    init_explorerbrowser(This);
    init_toolbar(This, hwnd);
    update_control_text(This);
    update_layout(This);

    return TRUE;
}

static LRESULT on_wm_size(FileDialogImpl *This)
{
    update_layout(This);
    return FALSE;
}

static LRESULT on_wm_getminmaxinfo(FileDialogImpl *This, LPARAM lparam)
{
    MINMAXINFO *mmi = (MINMAXINFO*)lparam;
    TRACE("%p (%p)\n", This, mmi);

    /* FIXME */
    mmi->ptMinTrackSize.x = 640;
    mmi->ptMinTrackSize.y = 480;

    return FALSE;
}

static LRESULT on_wm_destroy(FileDialogImpl *This)
{
    TRACE("%p\n", This);

    if(This->peb)
    {
        IExplorerBrowser_Destroy(This->peb);
        IExplorerBrowser_Release(This->peb);
        This->peb = NULL;
    }

    ctrl_container_reparent(This, NULL);
    This->dlg_hwnd = NULL;

    return TRUE;
}

static LRESULT on_idok(FileDialogImpl *This)
{
    TRACE("%p\n", This);

    if(SUCCEEDED(on_default_action(This)))
        EndDialog(This->dlg_hwnd, S_OK);

    return FALSE;
}

static LRESULT on_idcancel(FileDialogImpl *This)
{
    TRACE("%p\n", This);

    EndDialog(This->dlg_hwnd, HRESULT_FROM_WIN32(ERROR_CANCELLED));

    return FALSE;
}

static LRESULT on_browse_back(FileDialogImpl *This)
{
    TRACE("%p\n", This);
    IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEBACK);
    return FALSE;
}

static LRESULT on_browse_forward(FileDialogImpl *This)
{
    TRACE("%p\n", This);
    IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEFORWARD);
    return FALSE;
}

static LRESULT on_command_filetype(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
{
    if(HIWORD(wparam) == CBN_SELCHANGE)
    {
        IShellView *psv;
        HRESULT hr;
        LPWSTR filename;
        UINT prev_index = This->filetypeindex;

        This->filetypeindex = SendMessageW((HWND)lparam, CB_GETCURSEL, 0, 0);
        TRACE("File type selection changed to %d.\n", This->filetypeindex);

        if(prev_index == This->filetypeindex)
            return FALSE;

        hr = IExplorerBrowser_GetCurrentView(This->peb, &IID_IShellView, (void**)&psv);
        if(SUCCEEDED(hr))
        {
            IShellView_Refresh(psv);
            IShellView_Release(psv);
        }

        if(This->dlg_type == ITEMDLG_TYPE_SAVE && get_file_name(This, &filename))
        {
            WCHAR buf[MAX_PATH], extbuf[MAX_PATH], *ext;

            ext = get_first_ext_from_spec(extbuf, This->filterspecs[This->filetypeindex].pszSpec);
            if(ext)
            {
                lstrcpyW(buf, filename);

                if(PathMatchSpecW(buf, This->filterspecs[prev_index].pszSpec))
                    PathRemoveExtensionW(buf);

                lstrcatW(buf, ext);
                set_file_name(This, buf);
            }
            CoTaskMemFree(filename);
        }
    }

    return FALSE;
}

static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
{
    switch(LOWORD(wparam))
    {
    case IDOK:                return on_idok(This);
    case IDCANCEL:            return on_idcancel(This);
    case IDC_NAVBACK:         return on_browse_back(This);
    case IDC_NAVFORWARD:      return on_browse_forward(This);
    case IDC_FILETYPE:        return on_command_filetype(This, wparam, lparam);
    default:                  TRACE("Unknown command.\n");
    }
    return FALSE;
}

static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
    FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);

    switch(umessage)
    {
    case WM_INITDIALOG:       return on_wm_initdialog(hwnd, lparam);
    case WM_COMMAND:          return on_wm_command(This, wparam, lparam);
    case WM_SIZE:             return on_wm_size(This);
    case WM_GETMINMAXINFO:    return on_wm_getminmaxinfo(This, lparam);
    case WM_DESTROY:          return on_wm_destroy(This);
    }

    return FALSE;
}

static HRESULT create_dialog(FileDialogImpl *This, HWND parent)
{
    INT_PTR res;

    SetLastError(0);
    res = DialogBoxParamW(COMDLG32_hInstance,
                          MAKEINTRESOURCEW(NEWFILEOPENV3ORD),
                          parent, itemdlg_dlgproc, (LPARAM)This);
    This->dlg_hwnd = NULL;
    if(res == -1)
    {
        ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
        return E_FAIL;
    }

    TRACE("Returning 0x%08x\n", (HRESULT)res);
    return (HRESULT)res;
}

/**************************************************************************
 * IFileDialog implementation
 */
static inline FileDialogImpl *impl_from_IFileDialog2(IFileDialog2 *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialog2_iface);
}

static HRESULT WINAPI IFileDialog2_fnQueryInterface(IFileDialog2 *iface,
                                                    REFIID riid,
                                                    void **ppvObject)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);

    *ppvObject = NULL;
    if(IsEqualGUID(riid, &IID_IUnknown) ||
       IsEqualGUID(riid, &IID_IFileDialog) ||
       IsEqualGUID(riid, &IID_IFileDialog2))
    {
        *ppvObject = iface;
    }
    else if(IsEqualGUID(riid, &IID_IFileOpenDialog) && This->dlg_type == ITEMDLG_TYPE_OPEN)
    {
        *ppvObject = &This->u.IFileOpenDialog_iface;
    }
    else if(IsEqualGUID(riid, &IID_IFileSaveDialog) && This->dlg_type == ITEMDLG_TYPE_SAVE)
    {
        *ppvObject = &This->u.IFileSaveDialog_iface;
    }
    else if(IsEqualGUID(riid, &IID_IExplorerBrowserEvents))
    {
        *ppvObject = &This->IExplorerBrowserEvents_iface;
    }
    else if(IsEqualGUID(riid, &IID_IServiceProvider))
    {
        *ppvObject = &This->IServiceProvider_iface;
    }
    else if(IsEqualGUID(&IID_ICommDlgBrowser3, riid) ||
            IsEqualGUID(&IID_ICommDlgBrowser2, riid) ||
            IsEqualGUID(&IID_ICommDlgBrowser, riid))
    {
        *ppvObject = &This->ICommDlgBrowser3_iface;
    }
    else if(IsEqualGUID(&IID_IOleWindow, riid))
    {
        *ppvObject = &This->IOleWindow_iface;
    }
    else if(IsEqualGUID(riid, &IID_IFileDialogCustomize) ||
            IsEqualGUID(riid, &IID_IFileDialogCustomizeAlt))
    {
        *ppvObject = &This->IFileDialogCustomize_iface;
    }
    else
        FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid));

    if(*ppvObject)
    {
        IUnknown_AddRef((IUnknown*)*ppvObject);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI IFileDialog2_fnAddRef(IFileDialog2 *iface)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    LONG ref = InterlockedIncrement(&This->ref);
    TRACE("%p - ref %d\n", This, ref);

    return ref;
}

static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    LONG ref = InterlockedDecrement(&This->ref);
    TRACE("%p - ref %d\n", This, ref);

    if(!ref)
    {
        UINT i;
        for(i = 0; i < This->filterspec_count; i++)
        {
            LocalFree((void*)This->filterspecs[i].pszName);
            LocalFree((void*)This->filterspecs[i].pszSpec);
        }
        HeapFree(GetProcessHeap(), 0, This->filterspecs);

        DestroyWindow(This->cctrls_hwnd);

        if(This->psi_defaultfolder) IShellItem_Release(This->psi_defaultfolder);
        if(This->psi_setfolder)     IShellItem_Release(This->psi_setfolder);
        if(This->psi_folder)        IShellItem_Release(This->psi_folder);
        if(This->psia_selection)    IShellItemArray_Release(This->psia_selection);
        if(This->psia_results)      IShellItemArray_Release(This->psia_results);

        LocalFree(This->set_filename);
        LocalFree(This->default_ext);
        LocalFree(This->custom_title);
        LocalFree(This->custom_okbutton);
        LocalFree(This->custom_cancelbutton);
        LocalFree(This->custom_filenamelabel);

        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI IFileDialog2_fnShow(IFileDialog2 *iface, HWND hwndOwner)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", iface, hwndOwner);

    return create_dialog(This, hwndOwner);
}

static HRESULT WINAPI IFileDialog2_fnSetFileTypes(IFileDialog2 *iface, UINT cFileTypes,
                                                  const COMDLG_FILTERSPEC *rgFilterSpec)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    UINT i;
    TRACE("%p (%d, %p)\n", This, cFileTypes, rgFilterSpec);

    if(This->filterspecs)
        return E_UNEXPECTED;

    if(!rgFilterSpec)
        return E_INVALIDARG;

    if(!cFileTypes)
        return S_OK;

    This->filterspecs = HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC)*cFileTypes);
    for(i = 0; i < cFileTypes; i++)
    {
        This->filterspecs[i].pszName = StrDupW(rgFilterSpec[i].pszName);
        This->filterspecs[i].pszSpec = StrDupW(rgFilterSpec[i].pszSpec);
    }
    This->filterspec_count = cFileTypes;

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetFileTypeIndex(IFileDialog2 *iface, UINT iFileType)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%d)\n", This, iFileType);

    if(!This->filterspecs)
        return E_FAIL;

    if(iFileType >= This->filterspec_count)
        This->filetypeindex = This->filterspec_count - 1;
    else
        This->filetypeindex = iFileType;

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnGetFileTypeIndex(IFileDialog2 *iface, UINT *piFileType)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", This, piFileType);

    if(!piFileType)
        return E_INVALIDARG;

    *piFileType = This->filetypeindex;

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnAdvise(IFileDialog2 *iface, IFileDialogEvents *pfde, DWORD *pdwCookie)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    events_client *client;
    TRACE("%p (%p, %p)\n", This, pfde, pdwCookie);

    if(!pfde || !pdwCookie)
        return E_INVALIDARG;

    client = HeapAlloc(GetProcessHeap(), 0, sizeof(events_client));
    client->pfde = pfde;
    client->cookie = ++This->events_next_cookie;

    IFileDialogEvents_AddRef(pfde);
    *pdwCookie = client->cookie;

    list_add_tail(&This->events_clients, &client->entry);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnUnadvise(IFileDialog2 *iface, DWORD dwCookie)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    events_client *client, *found = NULL;
    TRACE("%p (%d)\n", This, dwCookie);

    LIST_FOR_EACH_ENTRY(client, &This->events_clients, events_client, entry)
    {
        if(client->cookie == dwCookie)
        {
            found = client;
            break;
        }
    }

    if(found)
    {
        list_remove(&found->entry);
        IFileDialogEvents_Release(found->pfde);
        HeapFree(GetProcessHeap(), 0, found);
        return S_OK;
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS fos)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (0x%x)\n", This, fos);

    This->options = fos;

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnGetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS *pfos)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", This, pfos);

    if(!pfos)
        return E_INVALIDARG;

    *pfos = This->options;

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetDefaultFolder(IFileDialog2 *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", This, psi);
    if(This->psi_defaultfolder)
        IShellItem_Release(This->psi_defaultfolder);

    This->psi_defaultfolder = psi;

    if(This->psi_defaultfolder)
        IShellItem_AddRef(This->psi_defaultfolder);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetFolder(IFileDialog2 *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", This, psi);
    if(This->psi_setfolder)
        IShellItem_Release(This->psi_setfolder);

    This->psi_setfolder = psi;

    if(This->psi_setfolder)
        IShellItem_AddRef(This->psi_setfolder);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnGetFolder(IFileDialog2 *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", This, ppsi);
    if(!ppsi)
        return E_INVALIDARG;

    /* FIXME:
       If the dialog is shown, return the current(ly selected) folder. */

    *ppsi = NULL;
    if(This->psi_folder)
        *ppsi = This->psi_folder;
    else if(This->psi_setfolder)
        *ppsi = This->psi_setfolder;
    else if(This->psi_defaultfolder)
        *ppsi = This->psi_defaultfolder;

    if(*ppsi)
    {
        IShellItem_AddRef(*ppsi);
        return S_OK;
    }

    return E_FAIL;
}

static HRESULT WINAPI IFileDialog2_fnGetCurrentSelection(IFileDialog2 *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    HRESULT hr;
    TRACE("%p (%p)\n", This, ppsi);

    if(!ppsi)
        return E_INVALIDARG;

    if(This->psia_selection)
    {
        /* FIXME: Check filename edit box */
        hr = IShellItemArray_GetItemAt(This->psia_selection, 0, ppsi);
        return hr;
    }

    return E_FAIL;
}

static HRESULT WINAPI IFileDialog2_fnSetFileName(IFileDialog2 *iface, LPCWSTR pszName)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", iface, debugstr_w(pszName));

    set_file_name(This, pszName);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnGetFileName(IFileDialog2 *iface, LPWSTR *pszName)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%p)\n", iface, pszName);

    if(!pszName)
        return E_INVALIDARG;

    *pszName = NULL;
    if(get_file_name(This, pszName))
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI IFileDialog2_fnSetTitle(IFileDialog2 *iface, LPCWSTR pszTitle)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", This, debugstr_w(pszTitle));

    LocalFree(This->custom_title);
    This->custom_title = StrDupW(pszTitle);
    update_control_text(This);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetOkButtonLabel(IFileDialog2 *iface, LPCWSTR pszText)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", This, debugstr_w(pszText));

    LocalFree(This->custom_okbutton);
    This->custom_okbutton = StrDupW(pszText);
    update_control_text(This);
    update_layout(This);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetFileNameLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", This, debugstr_w(pszLabel));

    LocalFree(This->custom_filenamelabel);
    This->custom_filenamelabel = StrDupW(pszLabel);
    update_control_text(This);
    update_layout(This);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnGetResult(IFileDialog2 *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    HRESULT hr;
    TRACE("%p (%p)\n", This, ppsi);

    if(!ppsi)
        return E_INVALIDARG;

    if(This->psia_results)
    {
        UINT item_count;
        hr = IShellItemArray_GetCount(This->psia_results, &item_count);
        if(SUCCEEDED(hr))
        {
            if(item_count != 1)
                return E_FAIL;

            /* Adds a reference. */
            hr = IShellItemArray_GetItemAt(This->psia_results, 0, ppsi);
        }

        return hr;
    }

    return E_UNEXPECTED;
}

static HRESULT WINAPI IFileDialog2_fnAddPlace(IFileDialog2 *iface, IShellItem *psi, FDAP fdap)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    FIXME("stub - %p (%p, %d)\n", This, psi, fdap);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialog2_fnSetDefaultExtension(IFileDialog2 *iface, LPCWSTR pszDefaultExtension)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", This, debugstr_w(pszDefaultExtension));

    LocalFree(This->default_ext);
    This->default_ext = StrDupW(pszDefaultExtension);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnClose(IFileDialog2 *iface, HRESULT hr)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (0x%08x)\n", This, hr);

    if(This->dlg_hwnd)
        EndDialog(This->dlg_hwnd, hr);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetClientGuid(IFileDialog2 *iface, REFGUID guid)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", This, debugstr_guid(guid));
    This->client_guid = *guid;
    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnClearClientData(IFileDialog2 *iface)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    FIXME("stub - %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialog2_fnSetFilter(IFileDialog2 *iface, IShellItemFilter *pFilter)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    FIXME("stub - %p (%p)\n", This, pFilter);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialog2_fnSetCancelButtonLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    TRACE("%p (%s)\n", This, debugstr_w(pszLabel));

    LocalFree(This->custom_cancelbutton);
    This->custom_cancelbutton = StrDupW(pszLabel);
    update_control_text(This);
    update_layout(This);

    return S_OK;
}

static HRESULT WINAPI IFileDialog2_fnSetNavigationRoot(IFileDialog2 *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileDialog2(iface);
    FIXME("stub - %p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static const IFileDialog2Vtbl vt_IFileDialog2 = {
    IFileDialog2_fnQueryInterface,
    IFileDialog2_fnAddRef,
    IFileDialog2_fnRelease,
    IFileDialog2_fnShow,
    IFileDialog2_fnSetFileTypes,
    IFileDialog2_fnSetFileTypeIndex,
    IFileDialog2_fnGetFileTypeIndex,
    IFileDialog2_fnAdvise,
    IFileDialog2_fnUnadvise,
    IFileDialog2_fnSetOptions,
    IFileDialog2_fnGetOptions,
    IFileDialog2_fnSetDefaultFolder,
    IFileDialog2_fnSetFolder,
    IFileDialog2_fnGetFolder,
    IFileDialog2_fnGetCurrentSelection,
    IFileDialog2_fnSetFileName,
    IFileDialog2_fnGetFileName,
    IFileDialog2_fnSetTitle,
    IFileDialog2_fnSetOkButtonLabel,
    IFileDialog2_fnSetFileNameLabel,
    IFileDialog2_fnGetResult,
    IFileDialog2_fnAddPlace,
    IFileDialog2_fnSetDefaultExtension,
    IFileDialog2_fnClose,
    IFileDialog2_fnSetClientGuid,
    IFileDialog2_fnClearClientData,
    IFileDialog2_fnSetFilter,
    IFileDialog2_fnSetCancelButtonLabel,
    IFileDialog2_fnSetNavigationRoot
};

/**************************************************************************
 * IFileOpenDialog
 */
static inline FileDialogImpl *impl_from_IFileOpenDialog(IFileOpenDialog *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileOpenDialog_iface);
}

static HRESULT WINAPI IFileOpenDialog_fnQueryInterface(IFileOpenDialog *iface,
                                                       REFIID riid, void **ppvObject)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI IFileOpenDialog_fnAddRef(IFileOpenDialog *iface)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI IFileOpenDialog_fnRelease(IFileOpenDialog *iface)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IFileOpenDialog_fnShow(IFileOpenDialog *iface, HWND hwndOwner)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
}

static HRESULT WINAPI IFileOpenDialog_fnSetFileTypes(IFileOpenDialog *iface, UINT cFileTypes,
                                                     const COMDLG_FILTERSPEC *rgFilterSpec)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
}

static HRESULT WINAPI IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog *iface, UINT iFileType)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
}

static HRESULT WINAPI IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog *iface, UINT *piFileType)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
}

static HRESULT WINAPI IFileOpenDialog_fnAdvise(IFileOpenDialog *iface, IFileDialogEvents *pfde,
                                               DWORD *pdwCookie)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
}

static HRESULT WINAPI IFileOpenDialog_fnUnadvise(IFileOpenDialog *iface, DWORD dwCookie)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
}

static HRESULT WINAPI IFileOpenDialog_fnSetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS fos)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
}

static HRESULT WINAPI IFileOpenDialog_fnGetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
}

static HRESULT WINAPI IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
}

static HRESULT WINAPI IFileOpenDialog_fnSetFolder(IFileOpenDialog *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
}

static HRESULT WINAPI IFileOpenDialog_fnGetFolder(IFileOpenDialog *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
}

static HRESULT WINAPI IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
}

static HRESULT WINAPI IFileOpenDialog_fnSetFileName(IFileOpenDialog *iface, LPCWSTR pszName)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
}

static HRESULT WINAPI IFileOpenDialog_fnGetFileName(IFileOpenDialog *iface, LPWSTR *pszName)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
}

static HRESULT WINAPI IFileOpenDialog_fnSetTitle(IFileOpenDialog *iface, LPCWSTR pszTitle)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
}

static HRESULT WINAPI IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog *iface, LPCWSTR pszText)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
}

static HRESULT WINAPI IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog *iface, LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
}

static HRESULT WINAPI IFileOpenDialog_fnGetResult(IFileOpenDialog *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
}

static HRESULT WINAPI IFileOpenDialog_fnAddPlace(IFileOpenDialog *iface, IShellItem *psi, FDAP fdap)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
}

static HRESULT WINAPI IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog *iface,
                                                            LPCWSTR pszDefaultExtension)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
}

static HRESULT WINAPI IFileOpenDialog_fnClose(IFileOpenDialog *iface, HRESULT hr)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
}

static HRESULT WINAPI IFileOpenDialog_fnSetClientGuid(IFileOpenDialog *iface, REFGUID guid)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
}

static HRESULT WINAPI IFileOpenDialog_fnClearClientData(IFileOpenDialog *iface)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IFileOpenDialog_fnSetFilter(IFileOpenDialog *iface, IShellItemFilter *pFilter)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
}

static HRESULT WINAPI IFileOpenDialog_fnGetResults(IFileOpenDialog *iface, IShellItemArray **ppenum)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    TRACE("%p (%p)\n", This, ppenum);

    *ppenum = This->psia_results;

    if(*ppenum)
    {
        IShellItemArray_AddRef(*ppenum);
        return S_OK;
    }

    return E_FAIL;
}

static HRESULT WINAPI IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog *iface, IShellItemArray **ppsai)
{
    FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
    TRACE("%p (%p)\n", This, ppsai);

    if(This->psia_selection)
    {
        *ppsai = This->psia_selection;
        IShellItemArray_AddRef(*ppsai);
        return S_OK;
    }

    return E_FAIL;
}

static const IFileOpenDialogVtbl vt_IFileOpenDialog = {
    IFileOpenDialog_fnQueryInterface,
    IFileOpenDialog_fnAddRef,
    IFileOpenDialog_fnRelease,
    IFileOpenDialog_fnShow,
    IFileOpenDialog_fnSetFileTypes,
    IFileOpenDialog_fnSetFileTypeIndex,
    IFileOpenDialog_fnGetFileTypeIndex,
    IFileOpenDialog_fnAdvise,
    IFileOpenDialog_fnUnadvise,
    IFileOpenDialog_fnSetOptions,
    IFileOpenDialog_fnGetOptions,
    IFileOpenDialog_fnSetDefaultFolder,
    IFileOpenDialog_fnSetFolder,
    IFileOpenDialog_fnGetFolder,
    IFileOpenDialog_fnGetCurrentSelection,
    IFileOpenDialog_fnSetFileName,
    IFileOpenDialog_fnGetFileName,
    IFileOpenDialog_fnSetTitle,
    IFileOpenDialog_fnSetOkButtonLabel,
    IFileOpenDialog_fnSetFileNameLabel,
    IFileOpenDialog_fnGetResult,
    IFileOpenDialog_fnAddPlace,
    IFileOpenDialog_fnSetDefaultExtension,
    IFileOpenDialog_fnClose,
    IFileOpenDialog_fnSetClientGuid,
    IFileOpenDialog_fnClearClientData,
    IFileOpenDialog_fnSetFilter,
    IFileOpenDialog_fnGetResults,
    IFileOpenDialog_fnGetSelectedItems
};

/**************************************************************************
 * IFileSaveDialog
 */
static inline FileDialogImpl *impl_from_IFileSaveDialog(IFileSaveDialog *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileSaveDialog_iface);
}

static HRESULT WINAPI IFileSaveDialog_fnQueryInterface(IFileSaveDialog *iface,
                                                       REFIID riid,
                                                       void **ppvObject)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI IFileSaveDialog_fnAddRef(IFileSaveDialog *iface)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI IFileSaveDialog_fnRelease(IFileSaveDialog *iface)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IFileSaveDialog_fnShow(IFileSaveDialog *iface, HWND hwndOwner)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
}

static HRESULT WINAPI IFileSaveDialog_fnSetFileTypes(IFileSaveDialog *iface, UINT cFileTypes,
                                                     const COMDLG_FILTERSPEC *rgFilterSpec)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
}

static HRESULT WINAPI IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog *iface, UINT iFileType)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
}

static HRESULT WINAPI IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog *iface, UINT *piFileType)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
}

static HRESULT WINAPI IFileSaveDialog_fnAdvise(IFileSaveDialog *iface, IFileDialogEvents *pfde,
                                               DWORD *pdwCookie)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
}

static HRESULT WINAPI IFileSaveDialog_fnUnadvise(IFileSaveDialog *iface, DWORD dwCookie)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
}

static HRESULT WINAPI IFileSaveDialog_fnSetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS fos)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
}

static HRESULT WINAPI IFileSaveDialog_fnGetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
}

static HRESULT WINAPI IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
}

static HRESULT WINAPI IFileSaveDialog_fnSetFolder(IFileSaveDialog *iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
}

static HRESULT WINAPI IFileSaveDialog_fnGetFolder(IFileSaveDialog *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
}

static HRESULT WINAPI IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
}

static HRESULT WINAPI IFileSaveDialog_fnSetFileName(IFileSaveDialog *iface, LPCWSTR pszName)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
}

static HRESULT WINAPI IFileSaveDialog_fnGetFileName(IFileSaveDialog *iface, LPWSTR *pszName)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
}

static HRESULT WINAPI IFileSaveDialog_fnSetTitle(IFileSaveDialog *iface, LPCWSTR pszTitle)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
}

static HRESULT WINAPI IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog *iface, LPCWSTR pszText)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
}

static HRESULT WINAPI IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog *iface, LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
}

static HRESULT WINAPI IFileSaveDialog_fnGetResult(IFileSaveDialog *iface, IShellItem **ppsi)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
}

static HRESULT WINAPI IFileSaveDialog_fnAddPlace(IFileSaveDialog *iface, IShellItem *psi, FDAP fdap)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
}

static HRESULT WINAPI IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog *iface,
                                                            LPCWSTR pszDefaultExtension)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
}

static HRESULT WINAPI IFileSaveDialog_fnClose(IFileSaveDialog *iface, HRESULT hr)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
}

static HRESULT WINAPI IFileSaveDialog_fnSetClientGuid(IFileSaveDialog *iface, REFGUID guid)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
}

static HRESULT WINAPI IFileSaveDialog_fnClearClientData(IFileSaveDialog *iface)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IFileSaveDialog_fnSetFilter(IFileSaveDialog *iface, IShellItemFilter *pFilter)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
}

static HRESULT WINAPI IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog* iface, IShellItem *psi)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    FIXME("stub - %p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileSaveDialog_fnSetProperties(IFileSaveDialog* iface, IPropertyStore *pStore)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    FIXME("stub - %p (%p)\n", This, pStore);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog* iface,
                                                               IPropertyDescriptionList *pList,
                                                               BOOL fAppendDefault)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    FIXME("stub - %p (%p, %d)\n", This, pList, fAppendDefault);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileSaveDialog_fnGetProperties(IFileSaveDialog* iface, IPropertyStore **ppStore)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    FIXME("stub - %p (%p)\n", This, ppStore);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileSaveDialog_fnApplyProperties(IFileSaveDialog* iface,
                                                        IShellItem *psi,
                                                        IPropertyStore *pStore,
                                                        HWND hwnd,
                                                        IFileOperationProgressSink *pSink)
{
    FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
    FIXME("%p (%p, %p, %p, %p)\n", This, psi, pStore, hwnd, pSink);
    return E_NOTIMPL;
}

static const IFileSaveDialogVtbl vt_IFileSaveDialog = {
    IFileSaveDialog_fnQueryInterface,
    IFileSaveDialog_fnAddRef,
    IFileSaveDialog_fnRelease,
    IFileSaveDialog_fnShow,
    IFileSaveDialog_fnSetFileTypes,
    IFileSaveDialog_fnSetFileTypeIndex,
    IFileSaveDialog_fnGetFileTypeIndex,
    IFileSaveDialog_fnAdvise,
    IFileSaveDialog_fnUnadvise,
    IFileSaveDialog_fnSetOptions,
    IFileSaveDialog_fnGetOptions,
    IFileSaveDialog_fnSetDefaultFolder,
    IFileSaveDialog_fnSetFolder,
    IFileSaveDialog_fnGetFolder,
    IFileSaveDialog_fnGetCurrentSelection,
    IFileSaveDialog_fnSetFileName,
    IFileSaveDialog_fnGetFileName,
    IFileSaveDialog_fnSetTitle,
    IFileSaveDialog_fnSetOkButtonLabel,
    IFileSaveDialog_fnSetFileNameLabel,
    IFileSaveDialog_fnGetResult,
    IFileSaveDialog_fnAddPlace,
    IFileSaveDialog_fnSetDefaultExtension,
    IFileSaveDialog_fnClose,
    IFileSaveDialog_fnSetClientGuid,
    IFileSaveDialog_fnClearClientData,
    IFileSaveDialog_fnSetFilter,
    IFileSaveDialog_fnSetSaveAsItem,
    IFileSaveDialog_fnSetProperties,
    IFileSaveDialog_fnSetCollectedProperties,
    IFileSaveDialog_fnGetProperties,
    IFileSaveDialog_fnApplyProperties
};

/**************************************************************************
 * IExplorerBrowserEvents implementation
 */
static inline FileDialogImpl *impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, IExplorerBrowserEvents_iface);
}

static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface,
                                                              REFIID riid, void **ppvObject)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);

    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    TRACE("%p\n", This);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    TRACE("%p\n", This);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface,
                                                                   PCIDLIST_ABSOLUTE pidlFolder)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    IShellItem *psi;
    HRESULT hr;
    TRACE("%p (%p)\n", This, pidlFolder);

    hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&psi);
    if(SUCCEEDED(hr))
    {
        hr = events_OnFolderChanging(This, psi);
        IShellItem_Release(psi);

        /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */
        if(hr == S_FALSE)
            hr = E_FAIL;

        return hr;
    }
    else
        ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder);

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface,
                                                             IShellView *psv)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    TRACE("%p (%p)\n", This, psv);
    return S_OK;
}

static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface,
                                                                    PCIDLIST_ABSOLUTE pidlFolder)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    HRESULT hr;
    TRACE("%p (%p)\n", This, pidlFolder);

    if(This->psi_folder)
        IShellItem_Release(This->psi_folder);

    hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&This->psi_folder);
    if(FAILED(hr))
    {
        ERR("Failed to get the current folder.\n");
        This->psi_folder = NULL;
    }

    events_OnFolderChange(This);

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface,
                                                                  PCIDLIST_ABSOLUTE pidlFolder)
{
    FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
    TRACE("%p (%p)\n", This, pidlFolder);
    return S_OK;
}

static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents = {
    IExplorerBrowserEvents_fnQueryInterface,
    IExplorerBrowserEvents_fnAddRef,
    IExplorerBrowserEvents_fnRelease,
    IExplorerBrowserEvents_fnOnNavigationPending,
    IExplorerBrowserEvents_fnOnViewCreated,
    IExplorerBrowserEvents_fnOnNavigationComplete,
    IExplorerBrowserEvents_fnOnNavigationFailed
};

/**************************************************************************
 * IServiceProvider implementation
 */
static inline FileDialogImpl *impl_from_IServiceProvider(IServiceProvider *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, IServiceProvider_iface);
}

static HRESULT WINAPI IServiceProvider_fnQueryInterface(IServiceProvider *iface,
                                                        REFIID riid, void **ppvObject)
{
    FileDialogImpl *This = impl_from_IServiceProvider(iface);
    TRACE("%p\n", This);
    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI IServiceProvider_fnAddRef(IServiceProvider *iface)
{
    FileDialogImpl *This = impl_from_IServiceProvider(iface);
    TRACE("%p\n", This);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface)
{
    FileDialogImpl *This = impl_from_IServiceProvider(iface);
    TRACE("%p\n", This);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IServiceProvider_fnQueryService(IServiceProvider *iface,
                                                      REFGUID guidService,
                                                      REFIID riid, void **ppv)
{
    FileDialogImpl *This = impl_from_IServiceProvider(iface);
    HRESULT hr = E_NOTIMPL;
    TRACE("%p (%s, %s, %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);

    *ppv = NULL;
    if(IsEqualGUID(guidService, &SID_STopLevelBrowser) && This->peb)
        hr = IExplorerBrowser_QueryInterface(This->peb, riid, ppv);
    else if(IsEqualGUID(guidService, &SID_SExplorerBrowserFrame))
        hr = IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppv);
    else
        FIXME("Interface %s requested from unknown service %s\n",
              debugstr_guid(riid), debugstr_guid(guidService));

    return hr;
}

static const IServiceProviderVtbl vt_IServiceProvider = {
    IServiceProvider_fnQueryInterface,
    IServiceProvider_fnAddRef,
    IServiceProvider_fnRelease,
    IServiceProvider_fnQueryService
};

/**************************************************************************
 * ICommDlgBrowser3 implementation
 */
static inline FileDialogImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, ICommDlgBrowser3_iface);
}

static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
                                                        REFIID riid, void **ppvObject)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
                                                          IShellView *shv)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    HRESULT hr;
    TRACE("%p (%p)\n", This, shv);

    hr = on_default_action(This);

    if(SUCCEEDED(hr))
        EndDialog(This->dlg_hwnd, S_OK);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
                                                       IShellView *shv, ULONG uChange )
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    IDataObject *new_selection;
    HRESULT hr;
    TRACE("%p (%p, %x)\n", This, shv, uChange);

    switch(uChange)
    {
    case CDBOSC_SELCHANGE:
        if(This->psia_selection)
        {
            IShellItemArray_Release(This->psia_selection);
            This->psia_selection = NULL;
        }

        hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&new_selection);
        if(SUCCEEDED(hr))
        {
            hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray,
                                                      (void**)&This->psia_selection);
            if(SUCCEEDED(hr))
            {
                fill_filename_from_selection(This);
                events_OnSelectionChange(This);
            }

            IDataObject_Release(new_selection);
        }
        break;
    default:
        TRACE("Unhandled state change\n");
    }
    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
                                                       IShellView *shv, LPCITEMIDLIST pidl)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    IShellItem *psi;
    LPWSTR filename;
    LPITEMIDLIST parent_pidl;
    HRESULT hr;
    ULONG attr;
    TRACE("%p (%p, %p)\n", This, shv, pidl);

    if(!This->filterspec_count)
        return S_OK;

    hr = SHGetIDListFromObject((IUnknown*)shv, &parent_pidl);
    if(SUCCEEDED(hr))
    {
        LPITEMIDLIST full_pidl = ILCombine(parent_pidl, pidl);
        hr = SHCreateItemFromIDList(full_pidl, &IID_IShellItem, (void**)&psi);
        ILFree(parent_pidl);
        ILFree(full_pidl);
    }
    if(FAILED(hr))
    {
        ERR("Failed to get shellitem (%08x).\n", hr);
        return S_OK;
    }

    hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER|SFGAO_LINK, &attr);
    if(FAILED(hr) || (attr & (SFGAO_FOLDER | SFGAO_LINK)))
    {
        IShellItem_Release(psi);
        return S_OK;
    }

    hr = S_OK;
    if(SUCCEEDED(IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename)))
    {
        if(!PathMatchSpecW(filename, This->filterspecs[This->filetypeindex].pszSpec))
            hr = S_FALSE;
        CoTaskMemFree(filename);
    }

    IShellItem_Release(psi);
    return hr;
}

static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
                                                IShellView *ppshv, DWORD dwNotifyType)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    FIXME("Stub: %p (%p, 0x%x)\n", This, ppshv, dwNotifyType);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
                                                            IShellView *pshv,
                                                            LPWSTR pszText, int cchMax)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    FIXME("Stub: %p (%p, %p, %d)\n", This, pshv, pszText, cchMax);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface, DWORD *pdwFlags)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    FIXME("Stub: %p (%p)\n", This, pdwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
                                                         IShellView *pshv, int iColumn)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    FIXME("Stub: %p (%p, %d)\n", This, pshv, iColumn);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
                                                          LPWSTR pszFileSpec, int cchFileSpec)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    FIXME("Stub: %p (%p, %d)\n", This, pszFileSpec, cchFileSpec);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
                                                          IShellView *pshv)
{
    FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
    FIXME("Stub: %p (%p)\n", This, pshv);
    return E_NOTIMPL;
}

static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
    ICommDlgBrowser3_fnQueryInterface,
    ICommDlgBrowser3_fnAddRef,
    ICommDlgBrowser3_fnRelease,
    ICommDlgBrowser3_fnOnDefaultCommand,
    ICommDlgBrowser3_fnOnStateChange,
    ICommDlgBrowser3_fnIncludeObject,
    ICommDlgBrowser3_fnNotify,
    ICommDlgBrowser3_fnGetDefaultMenuText,
    ICommDlgBrowser3_fnGetViewFlags,
    ICommDlgBrowser3_fnOnColumnClicked,
    ICommDlgBrowser3_fnGetCurrentFilter,
    ICommDlgBrowser3_fnOnPreviewCreated
};

/**************************************************************************
 * IOleWindow implementation
 */
static inline FileDialogImpl *impl_from_IOleWindow(IOleWindow *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, IOleWindow_iface);
}

static HRESULT WINAPI IOleWindow_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObject)
{
    FileDialogImpl *This = impl_from_IOleWindow(iface);
    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI IOleWindow_fnAddRef(IOleWindow *iface)
{
    FileDialogImpl *This = impl_from_IOleWindow(iface);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI IOleWindow_fnRelease(IOleWindow *iface)
{
    FileDialogImpl *This = impl_from_IOleWindow(iface);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IOleWindow_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMOde)
{
    FileDialogImpl *This = impl_from_IOleWindow(iface);
    FIXME("Stub: %p (%d)\n", This, fEnterMOde);
    return E_NOTIMPL;
}

static HRESULT WINAPI IOleWindow_fnGetWindow(IOleWindow *iface, HWND *phwnd)
{
    FileDialogImpl *This = impl_from_IOleWindow(iface);
    TRACE("%p (%p)\n", This, phwnd);
    *phwnd = This->dlg_hwnd;
    return S_OK;
}

static const IOleWindowVtbl vt_IOleWindow = {
    IOleWindow_fnQueryInterface,
    IOleWindow_fnAddRef,
    IOleWindow_fnRelease,
    IOleWindow_fnGetWindow,
    IOleWindow_fnContextSensitiveHelp
};

/**************************************************************************
 * IFileDialogCustomize implementation
 */
static inline FileDialogImpl *impl_from_IFileDialogCustomize(IFileDialogCustomize *iface)
{
    return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialogCustomize_iface);
}

static HRESULT WINAPI IFileDialogCustomize_fnQueryInterface(IFileDialogCustomize *iface,
                                                            REFIID riid, void **ppvObject)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
}

static ULONG WINAPI IFileDialogCustomize_fnAddRef(IFileDialogCustomize *iface)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    return IFileDialog2_AddRef(&This->IFileDialog2_iface);
}

static ULONG WINAPI IFileDialogCustomize_fnRelease(IFileDialogCustomize *iface)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    return IFileDialog2_Release(&This->IFileDialog2_iface);
}

static HRESULT WINAPI IFileDialogCustomize_fnEnableOpenDropDown(IFileDialogCustomize *iface,
                                                                DWORD dwIDCtl)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p (%d)\n", This, dwIDCtl);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddMenu(IFileDialogCustomize *iface,
                                                     DWORD dwIDCtl,
                                                     LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    TBBUTTON tbb;
    HRESULT hr;
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pszLabel);

    hr = cctrl_create_new(This, dwIDCtl, NULL, TOOLBARCLASSNAMEW,
                          TBSTYLE_FLAT | CCS_NODIVIDER, 0,
                          This->cctrl_def_height, &ctrl);
    if(SUCCEEDED(hr))
    {
        SendMessageW(ctrl->hwnd, TB_BUTTONSTRUCTSIZE, sizeof(tbb), 0);
        ctrl->type = IDLG_CCTRL_MENU;

        /* Add the actual button with a popup menu. */
        tbb.iBitmap = I_IMAGENONE;
        tbb.dwData = (DWORD_PTR)CreatePopupMenu();
        tbb.iString = (DWORD_PTR)pszLabel;
        tbb.fsState = TBSTATE_ENABLED;
        tbb.fsStyle = BTNS_WHOLEDROPDOWN;
        tbb.idCommand = 1;

        SendMessageW(ctrl->hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&tbb);
    }

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddPushButton(IFileDialogCustomize *iface,
                                                           DWORD dwIDCtl,
                                                           LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    HRESULT hr;
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pszLabel);

    hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_BUTTONW, BS_MULTILINE, 0,
                          This->cctrl_def_height, &ctrl);
    if(SUCCEEDED(hr))
        ctrl->type = IDLG_CCTRL_PUSHBUTTON;

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddComboBox(IFileDialogCustomize *iface,
                                                         DWORD dwIDCtl)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    HRESULT hr;
    TRACE("%p (%d)\n", This, dwIDCtl);

    hr =  cctrl_create_new(This, dwIDCtl, NULL, WC_COMBOBOXW, CBS_DROPDOWNLIST, 0,
                           This->cctrl_def_height, &ctrl);
    if(SUCCEEDED(hr))
        ctrl->type = IDLG_CCTRL_COMBOBOX;

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddRadioButtonList(IFileDialogCustomize *iface,
                                                                DWORD dwIDCtl)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p (%d)\n", This, dwIDCtl);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddCheckButton(IFileDialogCustomize *iface,
                                                            DWORD dwIDCtl,
                                                            LPCWSTR pszLabel,
                                                            BOOL bChecked)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    HRESULT hr;
    TRACE("%p (%d, %p, %d)\n", This, dwIDCtl, pszLabel, bChecked);

    hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_BUTTONW, BS_AUTOCHECKBOX, 0,
                          This->cctrl_def_height, &ctrl);
    if(SUCCEEDED(hr))
    {
        ctrl->type = IDLG_CCTRL_CHECKBUTTON;
        SendMessageW(ctrl->hwnd, BM_SETCHECK, bChecked ? BST_CHECKED : BST_UNCHECKED, 0);
    }

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddEditBox(IFileDialogCustomize *iface,
                                                        DWORD dwIDCtl,
                                                        LPCWSTR pszText)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    HRESULT hr;
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pszText);

    hr = cctrl_create_new(This, dwIDCtl, pszText, WC_EDITW, ES_AUTOHSCROLL, WS_EX_CLIENTEDGE,
                          This->cctrl_def_height, &ctrl);
    if(SUCCEEDED(hr))
        ctrl->type = IDLG_CCTRL_EDITBOX;

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddSeparator(IFileDialogCustomize *iface,
                                                          DWORD dwIDCtl)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    HRESULT hr;
    TRACE("%p (%d)\n", This, dwIDCtl);

    hr = cctrl_create_new(This, dwIDCtl, NULL, WC_STATICW, SS_ETCHEDHORZ, 0,
                          GetSystemMetrics(SM_CYEDGE), &ctrl);
    if(SUCCEEDED(hr))
        ctrl->type = IDLG_CCTRL_SEPARATOR;

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddText(IFileDialogCustomize *iface,
                                                     DWORD dwIDCtl,
                                                     LPCWSTR pszText)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl;
    HRESULT hr;
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pszText);

    hr = cctrl_create_new(This, dwIDCtl, pszText, WC_STATICW, 0, 0,
                          This->cctrl_def_height, &ctrl);
    if(SUCCEEDED(hr))
        ctrl->type = IDLG_CCTRL_TEXT;

    return hr;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetControlLabel(IFileDialogCustomize *iface,
                                                             DWORD dwIDCtl,
                                                             LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pszLabel);

    if(!ctrl) return E_INVALIDARG;

    switch(ctrl->type)
    {
    case IDLG_CCTRL_MENU:
    case IDLG_CCTRL_PUSHBUTTON:
    case IDLG_CCTRL_CHECKBUTTON:
    case IDLG_CCTRL_TEXT:
        SendMessageW(ctrl->hwnd, WM_SETTEXT, 0, (LPARAM)pszLabel);
        break;
    default:
        break;
    }

    return S_OK;
}

static HRESULT WINAPI IFileDialogCustomize_fnGetControlState(IFileDialogCustomize *iface,
                                                             DWORD dwIDCtl,
                                                             CDCONTROLSTATEF *pdwState)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pdwState);

    if(!ctrl) return E_NOTIMPL;

    *pdwState = ctrl->cdcstate;
    return S_OK;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetControlState(IFileDialogCustomize *iface,
                                                             DWORD dwIDCtl,
                                                             CDCONTROLSTATEF dwState)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This,dwIDCtl);
    TRACE("%p (%d, %x)\n", This, dwIDCtl, dwState);

    if(ctrl)
    {
        LONG wndstyle = GetWindowLongW(ctrl->hwnd, GWL_STYLE);

        if(dwState & CDCS_ENABLED)
            wndstyle &= ~(WS_DISABLED);
        else
            wndstyle |= WS_DISABLED;

        if(dwState & CDCS_VISIBLE)
            wndstyle |= WS_VISIBLE;
        else
            wndstyle &= ~(WS_VISIBLE);

        SetWindowLongW(ctrl->hwnd, GWL_STYLE, wndstyle);

        /* We save the state separately since at least one application
         * relies on being able to hide a control. */
        ctrl->cdcstate = dwState;
    }

    return S_OK;
}

static HRESULT WINAPI IFileDialogCustomize_fnGetEditBoxText(IFileDialogCustomize *iface,
                                                            DWORD dwIDCtl,
                                                            WCHAR **ppszText)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    WCHAR len, *text;
    TRACE("%p (%d, %p)\n", This, dwIDCtl, ppszText);

    if(!ctrl || !(len = SendMessageW(ctrl->hwnd, WM_GETTEXTLENGTH, 0, 0)))
        return E_FAIL;

    text = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
    if(!text) return E_FAIL;

    SendMessageW(ctrl->hwnd, WM_GETTEXT, len+1, (LPARAM)text);
    *ppszText = text;
    return S_OK;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetEditBoxText(IFileDialogCustomize *iface,
                                                            DWORD dwIDCtl,
                                                            LPCWSTR pszText)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %s)\n", This, dwIDCtl, debugstr_w(pszText));

    if(!ctrl || ctrl->type != IDLG_CCTRL_EDITBOX)
        return E_FAIL;

    SendMessageW(ctrl->hwnd, WM_SETTEXT, 0, (LPARAM)pszText);
    return S_OK;
}

static HRESULT WINAPI IFileDialogCustomize_fnGetCheckButtonState(IFileDialogCustomize *iface,
                                                                 DWORD dwIDCtl,
                                                                 BOOL *pbChecked)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pbChecked);

    if(ctrl)
        *pbChecked = (SendMessageW(ctrl->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED);

    return S_OK;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetCheckButtonState(IFileDialogCustomize *iface,
                                                                 DWORD dwIDCtl,
                                                                 BOOL bChecked)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %d)\n", This, dwIDCtl, bChecked);

    if(ctrl)
        SendMessageW(ctrl->hwnd, BM_SETCHECK, bChecked ? BST_CHECKED:BST_UNCHECKED, 0);

    return S_OK;
}

static UINT get_combobox_index_from_id(HWND cb_hwnd, DWORD dwIDItem)
{
    UINT count = SendMessageW(cb_hwnd, CB_GETCOUNT, 0, 0);
    UINT i;
    if(!count || (count == CB_ERR))
        return -1;

    for(i = 0; i < count; i++)
        if(SendMessageW(cb_hwnd, CB_GETITEMDATA, i, 0) == dwIDItem)
            return i;

    TRACE("Item with id %d not found in combobox %p (item count: %d)\n", dwIDItem, cb_hwnd, count);
    return -1;
}

static HRESULT WINAPI IFileDialogCustomize_fnAddControlItem(IFileDialogCustomize *iface,
                                                            DWORD dwIDCtl,
                                                            DWORD dwIDItem,
                                                            LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %d, %s)\n", This, dwIDCtl, dwIDItem, debugstr_w(pszLabel));

    if(!ctrl) return E_FAIL;

    switch(ctrl->type)
    {
    case IDLG_CCTRL_COMBOBOX:
    {
        UINT index;

        if(get_combobox_index_from_id(ctrl->hwnd, dwIDItem) != -1)
            return E_INVALIDARG;

        index = SendMessageW(ctrl->hwnd, CB_ADDSTRING, 0, (LPARAM)pszLabel);
        SendMessageW(ctrl->hwnd, CB_SETITEMDATA, index, dwIDItem);

        return S_OK;
    }
    case IDLG_CCTRL_MENU:
    {
        TBBUTTON tbb;
        SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);

        if(GetMenuState((HMENU)tbb.dwData, dwIDItem, MF_BYCOMMAND) != -1)
            return E_INVALIDARG;

        AppendMenuW((HMENU)tbb.dwData, MF_STRING, dwIDItem, pszLabel);
        return S_OK;
    }
    default:
        break;
    }

    return E_NOINTERFACE; /* win7 */
}

static HRESULT WINAPI IFileDialogCustomize_fnRemoveControlItem(IFileDialogCustomize *iface,
                                                               DWORD dwIDCtl,
                                                               DWORD dwIDItem)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %d)\n", This, dwIDCtl, dwIDItem);

    if(!ctrl) return E_FAIL;

    switch(ctrl->type)
    {
    case IDLG_CCTRL_COMBOBOX:
    {
        UINT i, count = SendMessageW(ctrl->hwnd, CB_GETCOUNT, 0, 0);
        if(!count || (count == CB_ERR))
            return E_FAIL;

        for(i = 0; i < count; i++)
            if(SendMessageW(ctrl->hwnd, CB_GETITEMDATA, i, 0) == dwIDItem)
            {
                if(SendMessageW(ctrl->hwnd, CB_DELETESTRING, i, 0) == CB_ERR)
                    return E_FAIL;
                return S_OK;
            }

        return E_UNEXPECTED;
    }
    case IDLG_CCTRL_MENU:
    {
        TBBUTTON tbb;
        HMENU hmenu;
        SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
        hmenu = (HMENU)tbb.dwData;

        if(!hmenu || !DeleteMenu(hmenu, dwIDItem, MF_BYCOMMAND))
            return E_UNEXPECTED;

        return S_OK;
    }
    default:
        break;
    }

    return E_FAIL;
}

static HRESULT WINAPI IFileDialogCustomize_fnRemoveAllControlItems(IFileDialogCustomize *iface,
                                                                   DWORD dwIDCtl)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    TRACE("%p (%d)\n", This, dwIDCtl);

    /* Not implemented by native */
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnGetControlItemState(IFileDialogCustomize *iface,
                                                                 DWORD dwIDCtl,
                                                                 DWORD dwIDItem,
                                                                 CDCONTROLSTATEF *pdwState)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetControlItemState(IFileDialogCustomize *iface,
                                                                 DWORD dwIDCtl,
                                                                 DWORD dwIDItem,
                                                                 CDCONTROLSTATEF dwState)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnGetSelectedControlItem(IFileDialogCustomize *iface,
                                                                    DWORD dwIDCtl,
                                                                    DWORD *pdwIDItem)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %p)\n", This, dwIDCtl, pdwIDItem);

    if(!ctrl) return E_FAIL;

    switch(ctrl->type)
    {
    case IDLG_CCTRL_COMBOBOX:
    {
        UINT index = SendMessageW(ctrl->hwnd, CB_GETCURSEL, 0, 0);
        if(index == CB_ERR)
            return E_FAIL;

        *pdwIDItem = SendMessageW(ctrl->hwnd, CB_GETITEMDATA, index, 0);
        return S_OK;
    }
    default:
        FIXME("Unsupported control type %d\n", ctrl->type);
    }

    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetSelectedControlItem(IFileDialogCustomize *iface,
                                                                    DWORD dwIDCtl,
                                                                    DWORD dwIDItem)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    customctrl *ctrl = get_cctrl(This, dwIDCtl);
    TRACE("%p (%d, %d)\n", This, dwIDCtl, dwIDItem);

    if(!ctrl) return E_INVALIDARG;

    switch(ctrl->type)
    {
    case IDLG_CCTRL_COMBOBOX:
    {
        UINT index = get_combobox_index_from_id(ctrl->hwnd, dwIDItem);

        if(index == -1)
            return E_INVALIDARG;

        if(SendMessageW(ctrl->hwnd, CB_SETCURSEL, index, 0) == CB_ERR)
            return E_FAIL;

        return S_OK;
    }
    default:
        FIXME("Unsupported control type %d\n", ctrl->type);
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI IFileDialogCustomize_fnStartVisualGroup(IFileDialogCustomize *iface,
                                                              DWORD dwIDCtl,
                                                              LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p (%d, %s)\n", This, dwIDCtl, debugstr_w(pszLabel));
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnEndVisualGroup(IFileDialogCustomize *iface)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnMakeProminent(IFileDialogCustomize *iface,
                                                           DWORD dwIDCtl)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p (%d)\n", This, dwIDCtl);
    return E_NOTIMPL;
}

static HRESULT WINAPI IFileDialogCustomize_fnSetControlItemText(IFileDialogCustomize *iface,
                                                                DWORD dwIDCtl,
                                                                DWORD dwIDItem,
                                                                LPCWSTR pszLabel)
{
    FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
    FIXME("stub - %p (%d, %d, %s)\n", This, dwIDCtl, dwIDItem, debugstr_w(pszLabel));
    return E_NOTIMPL;
}

static const IFileDialogCustomizeVtbl vt_IFileDialogCustomize = {
    IFileDialogCustomize_fnQueryInterface,
    IFileDialogCustomize_fnAddRef,
    IFileDialogCustomize_fnRelease,
    IFileDialogCustomize_fnEnableOpenDropDown,
    IFileDialogCustomize_fnAddMenu,
    IFileDialogCustomize_fnAddPushButton,
    IFileDialogCustomize_fnAddComboBox,
    IFileDialogCustomize_fnAddRadioButtonList,
    IFileDialogCustomize_fnAddCheckButton,
    IFileDialogCustomize_fnAddEditBox,
    IFileDialogCustomize_fnAddSeparator,
    IFileDialogCustomize_fnAddText,
    IFileDialogCustomize_fnSetControlLabel,
    IFileDialogCustomize_fnGetControlState,
    IFileDialogCustomize_fnSetControlState,
    IFileDialogCustomize_fnGetEditBoxText,
    IFileDialogCustomize_fnSetEditBoxText,
    IFileDialogCustomize_fnGetCheckButtonState,
    IFileDialogCustomize_fnSetCheckButtonState,
    IFileDialogCustomize_fnAddControlItem,
    IFileDialogCustomize_fnRemoveControlItem,
    IFileDialogCustomize_fnRemoveAllControlItems,
    IFileDialogCustomize_fnGetControlItemState,
    IFileDialogCustomize_fnSetControlItemState,
    IFileDialogCustomize_fnGetSelectedControlItem,
    IFileDialogCustomize_fnSetSelectedControlItem,
    IFileDialogCustomize_fnStartVisualGroup,
    IFileDialogCustomize_fnEndVisualGroup,
    IFileDialogCustomize_fnMakeProminent,
    IFileDialogCustomize_fnSetControlItemText
};

static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv, enum ITEMDLG_TYPE type)
{
    FileDialogImpl *fdimpl;
    HRESULT hr;
    IShellFolder *psf;
    TRACE("%p, %s, %p\n", pUnkOuter, debugstr_guid(riid), ppv);

    if(!ppv)
        return E_POINTER;
    if(pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    fdimpl = HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl));
    if(!fdimpl)
        return E_OUTOFMEMORY;

    fdimpl->ref = 1;
    fdimpl->IFileDialog2_iface.lpVtbl = &vt_IFileDialog2;
    fdimpl->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
    fdimpl->IServiceProvider_iface.lpVtbl = &vt_IServiceProvider;
    fdimpl->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
    fdimpl->IOleWindow_iface.lpVtbl = &vt_IOleWindow;
    fdimpl->IFileDialogCustomize_iface.lpVtbl = &vt_IFileDialogCustomize;

    if(type == ITEMDLG_TYPE_OPEN)
    {
        fdimpl->dlg_type = ITEMDLG_TYPE_OPEN;
        fdimpl->u.IFileOpenDialog_iface.lpVtbl = &vt_IFileOpenDialog;
        fdimpl->options = FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR;
        fdimpl->custom_title = fdimpl->custom_okbutton = NULL;
    }
    else
    {
        WCHAR buf[16];
        fdimpl->dlg_type = ITEMDLG_TYPE_SAVE;
        fdimpl->u.IFileSaveDialog_iface.lpVtbl = &vt_IFileSaveDialog;
        fdimpl->options = FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR;

        LoadStringW(COMDLG32_hInstance, IDS_SAVE, buf, sizeof(buf)/sizeof(WCHAR));
        fdimpl->custom_title = StrDupW(buf);
        fdimpl->custom_okbutton = StrDupW(buf);
    }

    fdimpl->filterspecs = NULL;
    fdimpl->filterspec_count = 0;
    fdimpl->filetypeindex = 0;

    fdimpl->psia_selection = fdimpl->psia_results = NULL;
    fdimpl->psi_setfolder = fdimpl->psi_folder = NULL;

    list_init(&fdimpl->events_clients);
    fdimpl->events_next_cookie = 0;

    fdimpl->dlg_hwnd = NULL;
    fdimpl->peb = NULL;

    fdimpl->set_filename = NULL;
    fdimpl->default_ext = NULL;
    fdimpl->custom_cancelbutton = fdimpl->custom_filenamelabel = NULL;

    fdimpl->client_guid = GUID_NULL;

    /* FIXME: The default folder setting should be restored for the
     * application if it was previously set. */
    SHGetDesktopFolder(&psf);
    SHGetItemFromObject((IUnknown*)psf, &IID_IShellItem, (void**)&fdimpl->psi_defaultfolder);
    IShellFolder_Release(psf);

    hr = init_custom_controls(fdimpl);
    if(FAILED(hr))
    {
        ERR("Failed to initialize custom controls (0x%08x).\n", hr);
        IUnknown_Release((IUnknown*)fdimpl);
        return E_FAIL;
    }

    hr = IUnknown_QueryInterface((IUnknown*)fdimpl, riid, ppv);
    IUnknown_Release((IUnknown*)fdimpl);
    return hr;
}

HRESULT FileOpenDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
    return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_OPEN);
}

HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
    return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_SAVE);
}
