/*
 * Copyright 2000 Eric Pouech
 * Copyright 2003 Dmitry Timoshkov
 *
 * 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
 *
 * FIXME:
 * Add support for all remaining MCI_ commands and MCIWNDM_ messages.
 * Add support for MCIWNDF_RECORD.
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "winternl.h"
#include "vfw.h"
#include "digitalv.h"
#include "commctrl.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mci);

extern HMODULE MSVFW32_hModule;
static const WCHAR mciWndClassW[] = {'M','C','I','W','n','d','C','l','a','s','s',0};

typedef struct
{
    DWORD       dwStyle;
    MCIDEVICEID mci;
    HDRVR       hdrv;
    int         alias;
    UINT        dev_type;
    UINT        mode;
    LONG        position;
    SIZE        size; /* size of the original frame rect */
    int         zoom;
    LPWSTR      lpName;
    HWND        hWnd, hwndOwner;
    UINT        uTimer;
    MCIERROR    lasterror;
    WCHAR       return_string[128];
    WORD        active_timer, inactive_timer;
} MCIWndInfo;

static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

#define CTL_PLAYSTOP    0x3200
#define CTL_MENU        0x3201
#define CTL_TRACKBAR    0x3202

/***********************************************************************
 *                MCIWndRegisterClass                [MSVFW32.@]
 *
 * NOTE: Native always uses its own hInstance
 */
BOOL VFWAPIV MCIWndRegisterClass(void)
{
    WNDCLASSW wc;

    /* Since we are going to register a class belonging to MSVFW32
     * and later we will create windows with a different hInstance
     * CS_GLOBALCLASS is needed. And because the second attempt
     * to register a global class will fail we need to test whether
     * the class was already registered.
     */
    wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC | CS_GLOBALCLASS;
    wc.lpfnWndProc = MCIWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(MCIWndInfo*);
    wc.hInstance = MSVFW32_hModule;
    wc.hIcon = 0;
    wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDC_ARROW));
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = mciWndClassW;

    if (RegisterClassW(&wc)) return TRUE;
    if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE;

    return FALSE;
}

/***********************************************************************
 *                MCIWndCreateW                                [MSVFW32.@]
 */
HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
                           DWORD dwStyle, LPCWSTR szFile)
{
    TRACE("%p %p %x %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));

    MCIWndRegisterClass();

    if (!hInstance) hInstance = GetModuleHandleW(0);

    if (hwndParent)
        dwStyle |= WS_VISIBLE | WS_BORDER /*| WS_CHILD*/;
    else
        dwStyle |= WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;

    return CreateWindowExW(0, mciWndClassW, NULL,
                           dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                           0, 0, 300, 0,
                           hwndParent, 0, hInstance, (LPVOID)szFile);
}

/***********************************************************************
 *                MCIWndCreate                [MSVFW32.@]
 *                MCIWndCreateA                [MSVFW32.@]
 */
HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
                           DWORD dwStyle, LPCSTR szFile)
{
    HWND ret;
    UNICODE_STRING fileW;

    if (szFile)
        RtlCreateUnicodeStringFromAsciiz(&fileW, szFile);
    else
        fileW.Buffer = NULL;

    ret = MCIWndCreateW(hwndParent, hInstance, dwStyle, fileW.Buffer);

    RtlFreeUnicodeString(&fileW);
    return ret;
}

static inline void MCIWND_notify_mode(MCIWndInfo *mwi)
{
    if (mwi->dwStyle & MCIWNDF_NOTIFYMODE)
    {
        UINT new_mode = SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0);
        if (new_mode != mwi->mode)
        {
            mwi->mode = new_mode;
            SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)mwi->hWnd, new_mode);
        }
    }
}

static inline void MCIWND_notify_pos(MCIWndInfo *mwi)
{
    if (mwi->dwStyle & MCIWNDF_NOTIFYPOS)
    {
        LONG new_pos = SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 0, 0);
        if (new_pos != mwi->position)
        {
            mwi->position = new_pos;
            SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYPOS, (WPARAM)mwi->hWnd, new_pos);
        }
    }
}

static inline void MCIWND_notify_size(MCIWndInfo *mwi)
{
    if (mwi->dwStyle & MCIWNDF_NOTIFYSIZE)
        SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYSIZE, (WPARAM)mwi->hWnd, 0);
}

static inline void MCIWND_notify_error(MCIWndInfo *mwi)
{
    if (mwi->dwStyle & MCIWNDF_NOTIFYERROR)
        SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYERROR, (WPARAM)mwi->hWnd, (LPARAM)mwi->lasterror);
}

static void MCIWND_UpdateState(MCIWndInfo *mwi)
{
    WCHAR buffer[1024];

    if (!mwi->mci)
    {
        /* FIXME: get this from resources */
        static const WCHAR no_deviceW[] = {'N','o',' ','D','e','v','i','c','e',0};
        SetWindowTextW(mwi->hWnd, no_deviceW);
        return;
    }

    MCIWND_notify_pos(mwi);

    if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
        SendDlgItemMessageW(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, TRUE, mwi->position);

    if (!(mwi->dwStyle & MCIWNDF_SHOWALL))
        return;

    if ((mwi->dwStyle & MCIWNDF_SHOWNAME) && mwi->lpName)
        strcpyW(buffer, mwi->lpName);
    else
        *buffer = 0;

    if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
    {
        static const WCHAR spaceW[] = {' ',0};
        static const WCHAR l_braceW[] = {'(',0};

        if (*buffer) strcatW(buffer, spaceW);
        strcatW(buffer, l_braceW);
    }

    if (mwi->dwStyle & MCIWNDF_SHOWPOS)
    {
        WCHAR posW[64];

        posW[0] = 0;
        SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 64, (LPARAM)posW);
        strcatW(buffer, posW);
    }

    if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
    {
        static const WCHAR dashW[] = {' ','-',' ',0};
        strcatW(buffer, dashW);
    }

    if (mwi->dwStyle & MCIWNDF_SHOWMODE)
    {
        WCHAR modeW[64];

        modeW[0] = 0;
        SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 64, (LPARAM)modeW);
        strcatW(buffer, modeW);
    }

    if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
    {
        static const WCHAR r_braceW[] = {')',0};
        strcatW(buffer, r_braceW);
    }

    TRACE("=> %s\n", debugstr_w(buffer));
    SetWindowTextW(mwi->hWnd, buffer);
}

static LRESULT MCIWND_Create(HWND hWnd, LPCREATESTRUCTW cs)
{
    HWND hChld;
    MCIWndInfo *mwi;
    static const WCHAR buttonW[] = {'b','u','t','t','o','n',0};

    mwi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*mwi));
    if (!mwi) return -1;

    SetWindowLongW(hWnd, 0, (LPARAM)mwi);

    mwi->dwStyle = cs->style;
    /* There is no need to show stats if there is no caption */
    if ((mwi->dwStyle & WS_CAPTION) != WS_CAPTION)
        mwi->dwStyle &= ~MCIWNDF_SHOWALL;

    mwi->hWnd = hWnd;
    mwi->hwndOwner = cs->hwndParent;
    mwi->active_timer = 500;
    mwi->inactive_timer = 2000;
    mwi->mode = MCI_MODE_NOT_READY;
    mwi->position = -1;
    mwi->zoom = 100;

    if (!(mwi->dwStyle & MCIWNDF_NOMENU))
    {
        static const WCHAR menuW[] = {'M','e','n','u',0};

        hChld = CreateWindowExW(0, buttonW, menuW, WS_CHILD|WS_VISIBLE, 32, cs->cy, 32, 32,
                                hWnd, (HMENU)CTL_MENU, cs->hInstance, 0L);
        TRACE("Get Button2: %p\n", hChld);
    }

    if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
    {
        INITCOMMONCONTROLSEX init;
        static const WCHAR playW[] = {'P','l','a','y',0};

        /* adding the other elements: play/stop button, menu button, status */
        hChld = CreateWindowExW(0, buttonW, playW, WS_CHILD|WS_VISIBLE, 0, cs->cy, 32, 32,
                                hWnd, (HMENU)CTL_PLAYSTOP, cs->hInstance, 0L);
        TRACE("Get Button1: %p\n", hChld);

        init.dwSize = sizeof(init);
        init.dwICC = ICC_BAR_CLASSES;
        InitCommonControlsEx(&init);

        hChld = CreateWindowExW(0, TRACKBAR_CLASSW, NULL, WS_CHILD|WS_VISIBLE, 64, cs->cy, cs->cx - 64, 32,
                                hWnd, (HMENU)CTL_TRACKBAR, cs->hInstance, 0L);
        TRACE("Get status: %p\n", hChld);
    }

    /* This sets the default window size */
    SendMessageW(hWnd, MCI_CLOSE, 0, 0);

    if (cs->lpCreateParams)
    {
        LPARAM lParam;

        /* MCI wnd class is prepared to be embedded as an MDI child window */
        if (cs->dwExStyle & WS_EX_MDICHILD)
        {
            MDICREATESTRUCTW *mdics = cs->lpCreateParams;
            lParam = mdics->lParam;
        }
        else
            lParam = (LPARAM)cs->lpCreateParams;

        /* If it's our internal class pointer, file name is a unicode string */
        if (cs->lpszClass == mciWndClassW)
            SendMessageW(hWnd, MCIWNDM_OPENW, 0, lParam);
        else
        {
            /* Otherwise let's try to figure out what string format is used */
            HWND parent = cs->hwndParent;
            if (!parent) parent = GetWindow(hWnd, GW_OWNER);

            SendMessageW(hWnd, IsWindowUnicode(parent) ? MCIWNDM_OPENW : MCIWNDM_OPENA, 0, lParam);
        }
    }

    return 0;
}

static void MCIWND_ToggleState(MCIWndInfo *mwi)
{
    switch (SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0))
    {
    case MCI_MODE_NOT_READY:
    case MCI_MODE_RECORD:
    case MCI_MODE_SEEK:
    case MCI_MODE_OPEN:
        TRACE("Cannot do much...\n");
        break;

    case MCI_MODE_PAUSE:
        SendMessageW(mwi->hWnd, MCI_RESUME, 0, 0);
        break;

    case MCI_MODE_PLAY:
        SendMessageW(mwi->hWnd, MCI_PAUSE, 0, 0);
        break;

    case MCI_MODE_STOP:
        SendMessageW(mwi->hWnd, MCI_STOP, 0, 0);
        break;
    }
}

static LRESULT MCIWND_Command(MCIWndInfo *mwi, WPARAM wParam, LPARAM lParam)
{
    switch (LOWORD(wParam))
    {
    case CTL_PLAYSTOP: MCIWND_ToggleState(mwi); break;
    case CTL_MENU:
    case CTL_TRACKBAR:
    default:
        FIXME("support for command %04x not implement yet\n", LOWORD(wParam));
    }
    return 0L;
}

static void MCIWND_notify_media(MCIWndInfo *mwi)
{
    if (mwi->dwStyle & (MCIWNDF_NOTIFYMEDIAA | MCIWNDF_NOTIFYMEDIAW))
    {
        if (!mwi->lpName)
        {
            static const WCHAR empty_str[1];
            SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)empty_str);
        }
        else
        {
            if (mwi->dwStyle & MCIWNDF_NOTIFYANSI)
            {
                char *ansi_name;
                int len;

                len = WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, NULL, 0, NULL, NULL);
                ansi_name = HeapAlloc(GetProcessHeap(), 0, len);
                WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, ansi_name, len, NULL, NULL);

                SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)ansi_name);

                HeapFree(GetProcessHeap(), 0, ansi_name);
            }
            else
                SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)mwi->lpName);
        }
    }
}

static MCIERROR mci_generic_command(MCIWndInfo *mwi, UINT cmd)
{
    MCI_GENERIC_PARMS mci_generic;

    mci_generic.dwCallback = 0;
    mwi->lasterror = mciSendCommandW(mwi->mci, cmd, 0, (DWORD_PTR)&mci_generic);

    if (mwi->lasterror)
        return mwi->lasterror;

    MCIWND_notify_mode(mwi);
    MCIWND_UpdateState(mwi);
    return 0;
}

static LRESULT mci_get_devcaps(MCIWndInfo *mwi, UINT cap)
{
    MCI_GETDEVCAPS_PARMS mci_devcaps;

    mci_devcaps.dwItem = cap;
    mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
                                   MCI_GETDEVCAPS_ITEM,
                                   (DWORD_PTR)&mci_devcaps);
    if (mwi->lasterror)
        return 0;

    return mci_devcaps.dwReturn;
}

static LRESULT MCIWND_KeyDown(MCIWndInfo *mwi, UINT key)
{
    TRACE("%p, key %04x\n", mwi->hWnd, key);

    switch(key)
    {
    case VK_ESCAPE:
        SendMessageW(mwi->hWnd, MCI_STOP, 0, 0);
        return 0;

    default:
        return 0;
    }
}

static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
    MCIWndInfo *mwi;

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

    mwi = (MCIWndInfo*)GetWindowLongPtrW(hWnd, 0);
    if (!mwi && wMsg != WM_CREATE)
        return DefWindowProcW(hWnd, wMsg, wParam, lParam);

    switch (wMsg)
    {
    case WM_CREATE:
        MCIWND_Create(hWnd, (CREATESTRUCTW *)lParam);
        break;

    case WM_DESTROY:
        if (mwi->uTimer)
            KillTimer(hWnd, mwi->uTimer);

        if (mwi->mci)
            SendMessageW(hWnd, MCI_CLOSE, 0, 0);

        HeapFree(GetProcessHeap(), 0, mwi);

        DestroyWindow(GetDlgItem(hWnd, CTL_MENU));
        DestroyWindow(GetDlgItem(hWnd, CTL_PLAYSTOP));
        DestroyWindow(GetDlgItem(hWnd, CTL_TRACKBAR));
        break;

    case WM_PAINT:
        {
            MCI_DGV_UPDATE_PARMS mci_update;
            PAINTSTRUCT ps;

            mci_update.hDC = (wParam) ? (HDC)wParam : BeginPaint(hWnd, &ps);

            mciSendCommandW(mwi->mci, MCI_UPDATE,
                            MCI_DGV_UPDATE_HDC | MCI_DGV_UPDATE_PAINT,
                            (DWORD_PTR)&mci_update);

            if (!wParam) EndPaint(hWnd, &ps);
            return 1;
        }

    case WM_COMMAND:
        return MCIWND_Command(mwi, wParam, lParam);

    case WM_KEYDOWN:
        return MCIWND_KeyDown(mwi, wParam);

    case WM_NCACTIVATE:
        if (mwi->uTimer)
        {
            KillTimer(hWnd, mwi->uTimer);
            mwi->uTimer = SetTimer(hWnd, 1, wParam ? mwi->active_timer : mwi->inactive_timer, NULL);
        }
        break;

    case WM_TIMER:
        MCIWND_UpdateState(mwi);
        return 0;

    case WM_SIZE:
        SetWindowPos(GetDlgItem(hWnd, CTL_PLAYSTOP), 0, 0, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
        SetWindowPos(GetDlgItem(hWnd, CTL_MENU), 0, 32, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
        SetWindowPos(GetDlgItem(hWnd, CTL_TRACKBAR), 0, 64, HIWORD(lParam) - 32, LOWORD(lParam) - 64, 32, SWP_NOACTIVATE);

        if (!(mwi->dwStyle & MCIWNDF_NOAUTOSIZEMOVIE))
        {
            RECT rc;

            rc.left = rc.top = 0;
            rc.right = LOWORD(lParam);
            rc.bottom = HIWORD(lParam);
            if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
                rc.bottom -= 32; /* subtract the height of the playbar */
            SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc);
        }
        MCIWND_notify_size(mwi);
        break;

    case MM_MCINOTIFY:
        MCIWND_notify_mode(mwi);
        MCIWND_UpdateState(mwi);
        return 0;

    case MCIWNDM_OPENA:
        {
            UNICODE_STRING nameW;
            TRACE("MCIWNDM_OPENA %s\n", debugstr_a((LPSTR)lParam));
            RtlCreateUnicodeStringFromAsciiz(&nameW, (LPCSTR)lParam);
            lParam = (LPARAM)nameW.Buffer;
        }
        /* fall through */
    case MCIWNDM_OPENW:
        {
            RECT rc;
            HCURSOR hCursor;
            MCI_OPEN_PARMSW mci_open;
            MCI_GETDEVCAPS_PARMS mci_devcaps;
            WCHAR aliasW[64];
            WCHAR drv_name[MAX_PATH];
            static const WCHAR formatW[] = {'%','d',0};
            static const WCHAR mci32W[] = {'m','c','i','3','2',0};
            static const WCHAR system_iniW[] = {'s','y','s','t','e','m','.','i','n','i',0};

            TRACE("MCIWNDM_OPENW %s\n", debugstr_w((LPWSTR)lParam));

            if (wParam == MCIWNDOPENF_NEW)
            {
                SendMessageW(hWnd, MCIWNDM_NEWW, 0, lParam);
                goto end_of_mci_open;
            }

            if (mwi->uTimer)
            {
                KillTimer(hWnd, mwi->uTimer);
                mwi->uTimer = 0;
            }

            hCursor = LoadCursorW(0, (LPWSTR)IDC_WAIT);
            hCursor = SetCursor(hCursor);

            mci_open.lpstrElementName = (LPWSTR)lParam;
            wsprintfW(aliasW, formatW, HandleToLong(hWnd) + 1);
            mci_open.lpstrAlias = aliasW;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_OPEN,
                                             MCI_OPEN_ELEMENT | MCI_OPEN_ALIAS | MCI_WAIT,
                                             (DWORD_PTR)&mci_open);
            SetCursor(hCursor);

            if (mwi->lasterror && !(mwi->dwStyle & MCIWNDF_NOERRORDLG))
            {
                /* FIXME: get the caption from resources */
                static const WCHAR caption[] = {'M','C','I',' ','E','r','r','o','r',0};
                WCHAR error_str[MAXERRORLENGTH];

                mciGetErrorStringW(mwi->lasterror, error_str, MAXERRORLENGTH);
                MessageBoxW(hWnd, error_str, caption, MB_ICONEXCLAMATION | MB_OK);
                MCIWND_notify_error(mwi);
                goto end_of_mci_open;
            }

            mwi->mci = mci_open.wDeviceID;
            mwi->alias = HandleToLong(hWnd) + 1;

            mwi->lpName = HeapAlloc(GetProcessHeap(), 0, (strlenW((LPWSTR)lParam) + 1) * sizeof(WCHAR));
            strcpyW(mwi->lpName, (LPWSTR)lParam);

            MCIWND_UpdateState(mwi);

            mci_devcaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
                                             MCI_GETDEVCAPS_ITEM,
                                             (DWORD_PTR)&mci_devcaps);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                goto end_of_mci_open;
            }

            mwi->dev_type = mci_devcaps.dwReturn;

            drv_name[0] = 0;
            SendMessageW(hWnd, MCIWNDM_GETDEVICEW, 256, (LPARAM)drv_name);
            if (drv_name[0] && GetPrivateProfileStringW(mci32W, drv_name, NULL,
                                            drv_name, MAX_PATH, system_iniW))
                mwi->hdrv = OpenDriver(drv_name, NULL, 0);

            if (mwi->dev_type == MCI_DEVTYPE_DIGITAL_VIDEO)
            {
                MCI_DGV_WINDOW_PARMSW mci_window;

                mci_window.hWnd = hWnd;
                mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WINDOW,
                                                 MCI_DGV_WINDOW_HWND,
                                                 (DWORD_PTR)&mci_window);
                if (mwi->lasterror)
                {
                    MCIWND_notify_error(mwi);
                    goto end_of_mci_open;
                }
            }

            if (SendMessageW(hWnd, MCIWNDM_GET_DEST, 0, (LPARAM)&rc) == 0)
            {
                mwi->size.cx = rc.right - rc.left;
                mwi->size.cy = rc.bottom - rc.top;

                rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100);
                rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100);
                SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc);
            }
            else
            {
                GetClientRect(hWnd, &rc);
                rc.bottom = rc.top;
            }

            if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
                rc.bottom += 32; /* add the height of the playbar */
            AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
            SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
                         rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

            SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L);
            SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1,
                                SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0));
            mwi->uTimer = SetTimer(hWnd, 1, mwi->active_timer, NULL);

            MCIWND_notify_media(mwi);

end_of_mci_open:
            if (wMsg == MCIWNDM_OPENA)
                HeapFree(GetProcessHeap(), 0, (void *)lParam);
            return mwi->lasterror;
        }

    case MCIWNDM_GETDEVICEID:
        TRACE("MCIWNDM_GETDEVICEID\n");
        return mwi->mci;

    case MCIWNDM_GETALIAS:
        TRACE("MCIWNDM_GETALIAS\n");
        return mwi->alias;

    case MCIWNDM_GET_SOURCE:
        {
            MCI_DGV_RECT_PARMS mci_rect;

            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE,
                                             MCI_DGV_WHERE_SOURCE,
                                             (DWORD_PTR)&mci_rect);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }
            *(RECT *)lParam = mci_rect.rc;
            TRACE("MCIWNDM_GET_SOURCE: %s\n", wine_dbgstr_rect(&mci_rect.rc));
            return 0;
        }

    case MCIWNDM_GET_DEST:
        {
            MCI_DGV_RECT_PARMS mci_rect;

            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE,
                                             MCI_DGV_WHERE_DESTINATION,
                                             (DWORD_PTR)&mci_rect);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }
            *(RECT *)lParam = mci_rect.rc;
            TRACE("MCIWNDM_GET_DEST: %s\n", wine_dbgstr_rect(&mci_rect.rc));
            return 0;
        }

    case MCIWNDM_PUT_SOURCE:
        {
            MCI_DGV_PUT_PARMS mci_put;

            mci_put.rc = *(RECT *)lParam;
            TRACE("MCIWNDM_PUT_SOURCE: %s\n", wine_dbgstr_rect(&mci_put.rc));
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
                                             MCI_DGV_PUT_SOURCE,
                                             (DWORD_PTR)&mci_put);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }
            return 0;
        }

    case MCIWNDM_PUT_DEST:
        {
            MCI_DGV_PUT_PARMS mci_put;

            mci_put.rc = *(RECT *)lParam;
            TRACE("MCIWNDM_PUT_DEST: %s\n", wine_dbgstr_rect(&mci_put.rc));

            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
                                             MCI_DGV_PUT_DESTINATION | MCI_DGV_RECT,
                                             (DWORD_PTR)&mci_put);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }
            return 0;
        }

    case MCIWNDM_GETLENGTH:
        {
            MCI_STATUS_PARMS mci_status;

            mci_status.dwItem = MCI_STATUS_LENGTH;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
                                             MCI_STATUS_ITEM,
                                             (DWORD_PTR)&mci_status);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return 0;
            }
            TRACE("MCIWNDM_GETLENGTH: %ld\n", mci_status.dwReturn);
            return mci_status.dwReturn;
        }

    case MCIWNDM_GETSTART:
        {
            MCI_STATUS_PARMS mci_status;

            mci_status.dwItem = MCI_STATUS_POSITION;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
                                             MCI_STATUS_ITEM | MCI_STATUS_START,
                                             (DWORD_PTR)&mci_status);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return 0;
            }
            TRACE("MCIWNDM_GETSTART: %ld\n", mci_status.dwReturn);
            return mci_status.dwReturn;
        }

    case MCIWNDM_GETEND:
        {
            LRESULT start, length;

            start = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
            length = SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
            TRACE("MCIWNDM_GETEND: %ld\n", start + length);
            return (start + length);
        }

    case MCIWNDM_GETPOSITIONA:
    case MCIWNDM_GETPOSITIONW:
        {
            MCI_STATUS_PARMS mci_status;

            TRACE("MCIWNDM_GETPOSITION\n");

            /* get position string if requested */
            if (wParam && lParam)
            {
                if (wMsg == MCIWNDM_GETPOSITIONA)
                {
                    char cmd[64];

                    wsprintfA(cmd, "status %d position", mwi->alias);
                    mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
                }
                else
                {

                    WCHAR cmdW[64];
                    static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','p','o','s','i','t','i','o','n',0};

                    wsprintfW(cmdW, formatW, mwi->alias);
                    mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
                }

                if (mwi->lasterror)
                    return 0;
            }

            mci_status.dwItem = MCI_STATUS_POSITION;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
                                             MCI_STATUS_ITEM,
                                             (DWORD_PTR)&mci_status);
            if (mwi->lasterror)
                return 0;

            return mci_status.dwReturn;
        }

    case MCIWNDM_GETMODEA:
    case MCIWNDM_GETMODEW:
        {
            MCI_STATUS_PARMS mci_status;

            TRACE("MCIWNDM_GETMODE\n");

            if (!mwi->mci)
                return MCI_MODE_NOT_READY;

            /* get mode string if requested */
            if (wParam && lParam)
            {
                if (wMsg == MCIWNDM_GETMODEA)
                {
                    char cmd[64];

                    wsprintfA(cmd, "status %d mode", mwi->alias);
                    mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
                }
                else
                {

                    WCHAR cmdW[64];
                    static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','m','o','d','e',0};

                    wsprintfW(cmdW, formatW, mwi->alias);
                    mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
                }

                if (mwi->lasterror)
                    return MCI_MODE_NOT_READY;
            }

            mci_status.dwItem = MCI_STATUS_MODE;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
                                             MCI_STATUS_ITEM,
                                             (DWORD_PTR)&mci_status);
            if (mwi->lasterror)
                return MCI_MODE_NOT_READY;

            return mci_status.dwReturn;
        }

    case MCIWNDM_PLAYFROM:
        {
            MCI_PLAY_PARMS mci_play;

            TRACE("MCIWNDM_PLAYFROM %08lx\n", lParam);

            mci_play.dwCallback = (DWORD_PTR)hWnd;
            mci_play.dwFrom = lParam;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
                                             MCI_FROM | MCI_NOTIFY,
                                             (DWORD_PTR)&mci_play);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }

            MCIWND_notify_mode(mwi);
            MCIWND_UpdateState(mwi);
            return 0;
        }

    case MCIWNDM_PLAYTO:
        {
            MCI_PLAY_PARMS mci_play;

            TRACE("MCIWNDM_PLAYTO %08lx\n", lParam);

            mci_play.dwCallback = (DWORD_PTR)hWnd;
            mci_play.dwTo = lParam;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
                                             MCI_TO | MCI_NOTIFY,
                                             (DWORD_PTR)&mci_play);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }

            MCIWND_notify_mode(mwi);
            MCIWND_UpdateState(mwi);
            return 0;
        }

    case MCIWNDM_PLAYREVERSE:
        {
            MCI_PLAY_PARMS mci_play;
            DWORD flags = MCI_NOTIFY;

            TRACE("MCIWNDM_PLAYREVERSE %08lx\n", lParam);

            mci_play.dwCallback = (DWORD_PTR)hWnd;
            mci_play.dwFrom = lParam;
            switch (mwi->dev_type)
            {
            default:
            case MCI_DEVTYPE_ANIMATION:
                flags |= MCI_ANIM_PLAY_REVERSE;
                break;

            case MCI_DEVTYPE_DIGITAL_VIDEO:
                flags |= MCI_DGV_PLAY_REVERSE;
                break;

#ifdef MCI_VCR_PLAY_REVERSE
            case MCI_DEVTYPE_VCR:
                flags |= MCI_VCR_PLAY_REVERSE;
                break;
#endif

            case MCI_DEVTYPE_VIDEODISC:
                flags |= MCI_VD_PLAY_REVERSE;
                break;

            }
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
                                             flags, (DWORD_PTR)&mci_play);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }

            MCIWND_notify_mode(mwi);
            MCIWND_UpdateState(mwi);
            return 0;
        }

    case MCIWNDM_GETERRORA:
        mciGetErrorStringA(mwi->lasterror, (LPSTR)lParam, wParam);
        TRACE("MCIWNDM_GETERRORA: %s\n", debugstr_an((LPSTR)lParam, wParam));
        return mwi->lasterror;

    case MCIWNDM_GETERRORW:
        mciGetErrorStringW(mwi->lasterror, (LPWSTR)lParam, wParam);
        TRACE("MCIWNDM_GETERRORW: %s\n", debugstr_wn((LPWSTR)lParam, wParam));
        return mwi->lasterror;

    case MCIWNDM_SETOWNER:
        TRACE("MCIWNDM_SETOWNER %p\n", (HWND)wParam);
        mwi->hwndOwner = (HWND)wParam;
        return 0;

    case MCIWNDM_SENDSTRINGA:
        {
            UNICODE_STRING stringW;

            TRACE("MCIWNDM_SENDSTRINGA %s\n", debugstr_a((LPCSTR)lParam));

            RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
            lParam = (LPARAM)stringW.Buffer;
        }
        /* fall through */
    case MCIWNDM_SENDSTRINGW:
        {
            WCHAR *cmdW, *p;

            TRACE("MCIWNDM_SENDSTRINGW %s\n", debugstr_w((LPCWSTR)lParam));

            p = strchrW((LPCWSTR)lParam, ' ');
            if (p)
            {
                static const WCHAR formatW[] = {'%','d',' ',0};
                int len, pos;

                pos = p - (WCHAR *)lParam + 1;
                len = lstrlenW((LPCWSTR)lParam) + 64;

                cmdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

                memcpy(cmdW, (void *)lParam, pos * sizeof(WCHAR));
                wsprintfW(cmdW + pos, formatW, mwi->alias);
                strcatW(cmdW, (WCHAR *)lParam + pos);
            }
            else
                cmdW = (LPWSTR)lParam;

            mwi->lasterror = mciSendStringW(cmdW, mwi->return_string,
                                            sizeof(mwi->return_string)/sizeof(mwi->return_string[0]),
                                            0);
            if (mwi->lasterror)
                MCIWND_notify_error(mwi);

            if (cmdW != (LPWSTR)lParam)
                HeapFree(GetProcessHeap(), 0, cmdW);

            if (wMsg == MCIWNDM_SENDSTRINGA)
                HeapFree(GetProcessHeap(), 0, (void *)lParam);

            MCIWND_UpdateState(mwi);
            return mwi->lasterror;
        }

    case MCIWNDM_RETURNSTRINGA:
        WideCharToMultiByte(CP_ACP, 0, mwi->return_string, -1, (LPSTR)lParam, wParam, NULL, NULL);
        TRACE("MCIWNDM_RETURNTRINGA %s\n", debugstr_an((LPSTR)lParam, wParam));
        return mwi->lasterror;

    case MCIWNDM_RETURNSTRINGW:
        lstrcpynW((LPWSTR)lParam, mwi->return_string, wParam);
        TRACE("MCIWNDM_RETURNTRINGW %s\n", debugstr_wn((LPWSTR)lParam, wParam));
        return mwi->lasterror;

    case MCIWNDM_SETTIMERS:
        TRACE("MCIWNDM_SETTIMERS active %d ms, inactive %d ms\n", (int)wParam, (int)lParam);
        mwi->active_timer = (WORD)wParam;
        mwi->inactive_timer = (WORD)lParam;
        return 0;

    case MCIWNDM_SETACTIVETIMER:
        TRACE("MCIWNDM_SETACTIVETIMER %d ms\n", (int)wParam);
        mwi->active_timer = (WORD)wParam;
        return 0;

    case MCIWNDM_SETINACTIVETIMER:
        TRACE("MCIWNDM_SETINACTIVETIMER %d ms\n", (int)wParam);
        mwi->inactive_timer = (WORD)wParam;
        return 0;

    case MCIWNDM_GETACTIVETIMER:
        TRACE("MCIWNDM_GETACTIVETIMER: %d ms\n", mwi->active_timer);
        return mwi->active_timer;

    case MCIWNDM_GETINACTIVETIMER:
        TRACE("MCIWNDM_GETINACTIVETIMER: %d ms\n", mwi->inactive_timer);
        return mwi->inactive_timer;

    case MCIWNDM_CHANGESTYLES:
        TRACE("MCIWNDM_CHANGESTYLES mask %08lx, set %08lx\n", wParam, lParam);
        /* FIXME: update the visual window state as well:
         * add/remove trackbar, autosize, etc.
         */
        mwi->dwStyle &= ~wParam;
        mwi->dwStyle |= lParam & wParam;
        return 0;

    case MCIWNDM_GETSTYLES:
        TRACE("MCIWNDM_GETSTYLES: %08x\n", mwi->dwStyle & 0xffff);
        return mwi->dwStyle & 0xffff;

    case MCIWNDM_GETDEVICEA:
        {
            MCI_SYSINFO_PARMSA mci_sysinfo;

            mci_sysinfo.lpstrReturn = (LPSTR)lParam;
            mci_sysinfo.dwRetSize = wParam;
            mwi->lasterror = mciSendCommandA(mwi->mci, MCI_SYSINFO,
                                             MCI_SYSINFO_INSTALLNAME,
                                             (DWORD_PTR)&mci_sysinfo);
            TRACE("MCIWNDM_GETDEVICEA: %s\n", debugstr_an((LPSTR)lParam, wParam));
            return 0;
        }

    case MCIWNDM_GETDEVICEW:
        {
            MCI_SYSINFO_PARMSW mci_sysinfo;

            mci_sysinfo.lpstrReturn = (LPWSTR)lParam;
            mci_sysinfo.dwRetSize = wParam;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SYSINFO,
                                             MCI_SYSINFO_INSTALLNAME,
                                             (DWORD_PTR)&mci_sysinfo);
            TRACE("MCIWNDM_GETDEVICEW: %s\n", debugstr_wn((LPWSTR)lParam, wParam));
            return 0;
        }

    case MCIWNDM_VALIDATEMEDIA:
        TRACE("MCIWNDM_VALIDATEMEDIA\n");
        if (mwi->mci)
        {
            SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
            SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
        }
        return 0;

    case MCIWNDM_GETFILENAMEA:
        TRACE("MCIWNDM_GETFILENAMEA: %s\n", debugstr_w(mwi->lpName));
        if (mwi->lpName)
            WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, (LPSTR)lParam, wParam, NULL, NULL);
        return 0;

    case MCIWNDM_GETFILENAMEW:
        TRACE("MCIWNDM_GETFILENAMEW: %s\n", debugstr_w(mwi->lpName));
        if (mwi->lpName)
            lstrcpynW((LPWSTR)lParam, mwi->lpName, wParam);
        return 0;

    case MCIWNDM_GETTIMEFORMATA:
    case MCIWNDM_GETTIMEFORMATW:
        {
            MCI_STATUS_PARMS mci_status;

            TRACE("MCIWNDM_GETTIMEFORMAT %08lx %08lx\n", wParam, lParam);

            /* get format string if requested */
            if (wParam && lParam)
            {
                if (wMsg == MCIWNDM_GETTIMEFORMATA)
                {
                    char cmd[64];

                    wsprintfA(cmd, "status %d time format", mwi->alias);
                    mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
                    if (mwi->lasterror)
                        return 0;
                }
                else
                {
                    WCHAR cmdW[64];
                    static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',0};

                    wsprintfW(cmdW, formatW, mwi->alias);
                    mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
                    if (mwi->lasterror)
                        return 0;
                }
            }

            mci_status.dwItem = MCI_STATUS_TIME_FORMAT ;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
                                             MCI_STATUS_ITEM,
                                             (DWORD_PTR)&mci_status);
            if (mwi->lasterror)
                return 0;

            return mci_status.dwReturn;
        }

    case MCIWNDM_SETTIMEFORMATA:
        {
            UNICODE_STRING stringW;

            TRACE("MCIWNDM_SETTIMEFORMATA %s\n", debugstr_a((LPSTR)lParam));

            RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
            lParam = (LPARAM)stringW.Buffer;
        }
        /* fall through */
    case MCIWNDM_SETTIMEFORMATW:
        {
            static const WCHAR formatW[] = {'s','e','t',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',' ',0};
            WCHAR *cmdW;

            TRACE("MCIWNDM_SETTIMEFORMATW %s\n", debugstr_w((LPWSTR)lParam));

            if (mwi->mci)
            {
                cmdW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW((LPCWSTR)lParam) + 64) * sizeof(WCHAR));
                wsprintfW(cmdW, formatW, mwi->alias);
                strcatW(cmdW, (WCHAR *)lParam);

                mwi->lasterror = mciSendStringW(cmdW, NULL, 0, 0);

                /* fix the range tracking according to the new time format */
                if (!mwi->lasterror)
                    SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1,
                                        SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0));

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

            if (wMsg == MCIWNDM_SETTIMEFORMATA)
                HeapFree(GetProcessHeap(), 0, (void *)lParam);

            return 0;
        }

    case MCIWNDM_CAN_PLAY:
        TRACE("MCIWNDM_CAN_PLAY\n");
        if (mwi->mci)
            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_PLAY);
        return 0;

    case MCIWNDM_CAN_RECORD:
        TRACE("MCIWNDM_CAN_RECORD\n");
        if (mwi->mci)
            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_RECORD);
        return 0;

    case MCIWNDM_CAN_SAVE:
        TRACE("MCIWNDM_CAN_SAVE\n");
        if (mwi->mci)
            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_SAVE);
        return 0;

    case MCIWNDM_CAN_EJECT:
        TRACE("MCIWNDM_CAN_EJECT\n");
        if (mwi->mci)
            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_EJECT);
        return 0;

    case MCIWNDM_CAN_WINDOW:
        TRACE("MCIWNDM_CAN_WINDOW\n");
        switch (mwi->dev_type)
        {
        case MCI_DEVTYPE_ANIMATION:
        case MCI_DEVTYPE_DIGITAL_VIDEO:
        case MCI_DEVTYPE_OVERLAY:
            return 1;
        }
        return 0;

    case MCIWNDM_CAN_CONFIG:
        TRACE("MCIWNDM_CAN_CONFIG\n");
        if (mwi->hdrv)
            return SendDriverMessage(mwi->hdrv, DRV_QUERYCONFIGURE, 0, 0);
        return 0;

    case MCIWNDM_SETZOOM:
        TRACE("MCIWNDM_SETZOOM %ld\n", lParam);
        mwi->zoom = lParam;

        if (mwi->mci && !(mwi->dwStyle & MCIWNDF_NOAUTOSIZEWINDOW))
        {
            RECT rc;

            rc.left = rc.top = 0;
            rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100);
            rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100);

            if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
                rc.bottom += 32; /* add the height of the playbar */
            AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
            SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
                         SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
        }
        return 0;

    case MCIWNDM_GETZOOM:
        TRACE("MCIWNDM_GETZOOM: %d\n", mwi->zoom);
        return mwi->zoom;

    case MCIWNDM_EJECT:
        {
            MCI_SET_PARMS mci_set;

            TRACE("MCIWNDM_EJECT\n");

            mci_set.dwCallback = (DWORD_PTR)hWnd;
            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SET,
                                             MCI_SET_DOOR_OPEN | MCI_NOTIFY,
                                             (DWORD_PTR)&mci_set);
            MCIWND_notify_mode(mwi);
            MCIWND_UpdateState(mwi);
            return mwi->lasterror;
        }

    case MCIWNDM_SETVOLUME:
    case MCIWNDM_GETVOLUME:
    case MCIWNDM_SETSPEED:
    case MCIWNDM_GETSPEED:
    case MCIWNDM_SETREPEAT:
    case MCIWNDM_GETREPEAT:
    case MCIWNDM_REALIZE:
    case MCIWNDM_GETPALETTE:
    case MCIWNDM_SETPALETTE:
    case MCIWNDM_NEWA:
    case MCIWNDM_NEWW:
    case MCIWNDM_PALETTEKICK:
    case MCIWNDM_OPENINTERFACE:
        FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER);
        return 0;

    case MCI_PLAY:
        {
            LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
            return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end);
        }

    case MCI_SEEK:
    case MCI_STEP:
        {
            MCI_SEEK_PARMS mci_seek; /* Layout is usable as MCI_XYZ_STEP_PARMS */
            DWORD flags = MCI_STEP == wMsg ? 0 :
                          MCIWND_START == lParam ? MCI_SEEK_TO_START :
                          MCIWND_END   == lParam ? MCI_SEEK_TO_END : MCI_TO;

            mci_seek.dwTo = lParam;
            mwi->lasterror = mciSendCommandW(mwi->mci, wMsg,
                                             flags, (DWORD_PTR)&mci_seek);
            if (mwi->lasterror)
            {
                MCIWND_notify_error(mwi);
                return mwi->lasterror;
            }
            /* update window to reflect the state */
            else InvalidateRect(hWnd, NULL, TRUE);
            return 0;
        }

    case MCI_CLOSE:
        {
            RECT rc;
            MCI_GENERIC_PARMS mci_generic;

            if (mwi->hdrv)
            {
                CloseDriver(mwi->hdrv, 0, 0);
                mwi->hdrv = 0;
            }

            if (mwi->mci)
            {
                mci_generic.dwCallback = 0;
                mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE,
                                                 0, (DWORD_PTR)&mci_generic);
                mwi->mci = 0;
            }

            mwi->mode = MCI_MODE_NOT_READY;
            mwi->position = -1;

            HeapFree(GetProcessHeap(), 0, mwi->lpName);
            mwi->lpName = NULL;
            MCIWND_UpdateState(mwi);

            GetClientRect(hWnd, &rc);
            rc.bottom = rc.top;
            if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
                rc.bottom += 32; /* add the height of the playbar */
            AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
            SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
                         rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

            MCIWND_notify_media(mwi);
            return 0;
        }

    case MCI_PAUSE:
    case MCI_STOP:
    case MCI_RESUME:
        mci_generic_command(mwi, wMsg);
        return mwi->lasterror;

    case MCI_CONFIGURE:
        if (mwi->hdrv)
            SendDriverMessage(mwi->hdrv, DRV_CONFIGURE, (LPARAM)hWnd, 0);
        return 0;

    case MCI_BREAK:
    case MCI_CAPTURE:
    case MCI_COPY:
    case MCI_CUE:
    case MCI_CUT:
    case MCI_DELETE:
    case MCI_ESCAPE:
    case MCI_FREEZE:
    case MCI_GETDEVCAPS:
    /*case MCI_INDEX:*/
    case MCI_INFO:
    case MCI_LIST:
    case MCI_LOAD:
    /*case MCI_MARK:*/
    case MCI_MONITOR:
    case MCI_OPEN:
    case MCI_PASTE:
    case MCI_PUT:
    case MCI_QUALITY:
    case MCI_REALIZE:
    case MCI_RECORD:
    case MCI_RESERVE:
    case MCI_RESTORE:
    case MCI_SAVE:
    case MCI_SET:
    case MCI_SETAUDIO:
    /*case MCI_SETTIMECODE:*/
    /*case MCI_SETTUNER:*/
    case MCI_SETVIDEO:
    case MCI_SIGNAL:
    case MCI_SPIN:
    case MCI_STATUS:
    case MCI_SYSINFO:
    case MCI_UNDO:
    case MCI_UNFREEZE:
    case MCI_UPDATE:
    case MCI_WHERE:
    case MCI_WINDOW:
        FIXME("support for MCI_ command %04x not implemented\n", wMsg);
        return 0;
    }

    if (wMsg >= WM_USER)
    {
        FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER);
        return 0;
    }

    if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
        return DefMDIChildProcW(hWnd, wMsg, wParam, lParam);

    return DefWindowProcW(hWnd, wMsg, wParam, lParam);
}
