MCI #4: Add support for many MCIWNDM_ messages and some MCI_ commands

Dmitry Timoshkov dmitry at baikal.ru
Tue Dec 30 10:48:06 CST 2003


Hello,

Please apply after MCI #3.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add support for many MCIWNDM_ messages and some MCI_ commands
    in the MCIWndClass implementation.
    MCIWndRegisterClass() takes no parameters according to Platform SDK
    headers.

diff -u cvs/hq/wine/dlls/msvideo/mciwnd.c wine/dlls/msvideo/mciwnd.c
--- cvs/hq/wine/dlls/msvideo/mciwnd.c   2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/msvideo/mciwnd.c  2003-12-30 23:28:23.000000000 +0800
@@ -17,14 +17,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * FIXME:
- * Add support for all remaining MCI_ and MCIWNDM_ messages.
- * Add support for MCIWNDF_NOTIFYMODE (all cases), MCIWNDF_NOTIFYPOS.
+ * Add support for all remaining MCI_ commands and MCIWNDM_ messages.
+ * Add support for all MCIWNDF_ flags.
  */
 
-#define COM_NO_WINDOWS_H
 #include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -48,16 +45,31 @@ 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;
 
 #define MCIWND_NOTIFY_MODE(info) \
     if ((info)->dwStyle & MCIWNDF_NOTIFYMODE) \
-        SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)(info)->hWnd, (LPARAM)SendMessageW((info)->hWnd, MCIWNDM_GETMODEW, 0, 0))
+    { \
+        UINT new_mode = SendMessageW((info)->hWnd, MCIWNDM_GETMODEW, 0, 0); \
+        if (new_mode != (info)->mode) \
+        { \
+            (info)->mode = new_mode; \
+            SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)(info)->hWnd, new_mode); \
+        } \
+    }
 
 #define MCIWND_NOTIFY_SIZE(info) \
     if ((info)->dwStyle & MCIWNDF_NOTIFYSIZE) \
@@ -69,6 +81,17 @@ typedef struct
 
 #define MCIWND_NOTIFY_MEDIA(info) MCIWND_notify_media(info)
 
+#define MCIWND_NOTIFY_POS(info) \
+    if ((info)->dwStyle & MCIWNDF_NOTIFYPOS) \
+    { \
+        long new_pos = SendMessageW((info)->hWnd, MCIWNDM_GETPOSITIONW, 0, 0); \
+        if (new_pos != (info)->position) \
+        { \
+            (info)->position = new_pos; \
+            SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYPOS, (WPARAM)(info)->hWnd, new_pos); \
+        } \
+    }
+
 static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
 
 #define CTL_PLAYSTOP    0x3200
@@ -80,7 +103,7 @@ static LRESULT WINAPI MCIWndProc(HWND hW
  *
  * NOTE: Native always uses its own hInstance
  */
-BOOL VFWAPIV MCIWndRegisterClass(HINSTANCE hInst)
+BOOL VFWAPIV MCIWndRegisterClass(void)
 {
     WNDCLASSW wc;
 
@@ -115,11 +138,12 @@ HWND VFWAPIV MCIWndCreateW(HWND hwndPare
 {
     TRACE("%p %p %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));
 
-    MCIWndRegisterClass(hInstance);
+    MCIWndRegisterClass();
 
-    /* window becomes visible after MCI_PLAY command in the case of MCIWNDF_NOOPEN */
-    if (dwStyle & MCIWNDF_NOOPEN)
-        dwStyle &= ~WS_VISIBLE;
+    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,
@@ -148,10 +172,23 @@ HWND VFWAPIV MCIWndCreateA(HWND hwndPare
     return ret;
 }
 
-static void MCIWND_UpdateText(MCIWndInfo *mwi)
+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_SHOWNAME) && mwi->lpName)
         strcpyW(buffer, mwi->lpName);
     else
@@ -168,8 +205,11 @@ static void MCIWND_UpdateText(MCIWndInfo
 
     if (mwi->dwStyle & MCIWNDF_SHOWPOS)
     {
-        static const WCHAR formatW[] = {'%','l','d',0};
-        sprintfW(buffer + strlenW(buffer), formatW, SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 0, 0));
+        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))
@@ -180,32 +220,16 @@ static void MCIWND_UpdateText(MCIWndInfo
 
     if (mwi->dwStyle & MCIWNDF_SHOWMODE)
     {
-        /* FIXME: get the status string from resources */
-        static const WCHAR not_readyW[] = {'n','o','t',' ','r','e','a','d','y',0};
-        static const WCHAR pausedW[] = {'p','a','u','s','e','d',0};
-        static const WCHAR playingW[] = {'p','l','a','y','i','n','g',0};
-        static const WCHAR stoppedW[] = {'s','t','o','p','p','e','d',0};
-        static const WCHAR openW[] = {'o','p','e','n',0};
-        static const WCHAR recordingW[] = {'r','e','c','o','r','d','i','n','g',0};
-        static const WCHAR seekingW[] = {'s','e','e','k','i','n','g',0};
-        static const WCHAR unknownW[] = {'?','?','?',0};
-
-        switch (SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0))
-        {
-            case MCI_MODE_NOT_READY: strcatW(buffer, not_readyW); break;
-            case MCI_MODE_PAUSE: strcatW(buffer, pausedW); break;
-            case MCI_MODE_PLAY: strcatW(buffer, playingW); break;
-            case MCI_MODE_STOP: strcatW(buffer, stoppedW); break;
-            case MCI_MODE_OPEN: strcatW(buffer, openW); break;
-            case MCI_MODE_RECORD: strcatW(buffer, recordingW); break;
-            case MCI_MODE_SEEK: strcatW(buffer, seekingW); break;
-            default: strcatW(buffer, unknownW); break;
-        }
+        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};
+        static const WCHAR r_braceW[] = {')',0};
         strcatW(buffer, r_braceW);
     }
 
@@ -219,21 +243,19 @@ static LRESULT MCIWND_Create(HWND hWnd, 
     MCIWndInfo *mwi;
     static const WCHAR buttonW[] = {'b','u','t','t','o','n',0};
 
-    /* This sets the default window size */
-    SendMessageW(hWnd, MCI_CLOSE, 0, 0);
-
-    mwi = HeapAlloc(GetProcessHeap(), 0, sizeof(*mwi));
+    mwi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*mwi));
     if (!mwi) return -1;
 
     SetWindowLongW(hWnd, 0, (LPARAM)mwi);
 
     mwi->dwStyle = cs->style;
-    mwi->mci = 0;
-    mwi->lpName = NULL;
-    mwi->uTimer = 0;
     mwi->hWnd = hWnd;
     mwi->hwndOwner = cs->hwndParent;
-    mwi->lasterror = 0;
+    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))
     {
@@ -263,9 +285,25 @@ static LRESULT MCIWND_Create(HWND hWnd, 
         TRACE("Get status: %p\n", hChld);
     }
 
-    SendMessageW(hWnd, MCIWNDM_OPENW, 0, (LPARAM)cs->lpCreateParams);
+    /* 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 = (MDICREATESTRUCTW *)cs->lpCreateParams;
+            lParam = mdics->lParam;
+        }
+        else
+            lParam = (LPARAM)cs->lpCreateParams;
+        /* yes, A variant of the message */
+        SendMessageW(hWnd, MCIWNDM_OPENA, 0, lParam);
+    }
 
-    MCIWND_UpdateText(mwi);
     return 0;
 }
 
@@ -302,19 +340,11 @@ static LRESULT MCIWND_Command(MCIWndInfo
     case CTL_MENU:
     case CTL_TRACKBAR:
     default:
-        MessageBoxA(0, "ooch", "NIY", MB_OK);
+        FIXME("support for command %04x not implement yet\n", LOWORD(wParam));
     }
     return 0L;
 }
 
-static void MCIWND_Timer(MCIWndInfo *mwi)
-{
-    LONG pos = SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 0, 0);
-    TRACE("%ld\n", pos);
-    SendDlgItemMessageW(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, TRUE, pos);
-    MCIWND_UpdateText(mwi);
-}
-
 static void MCIWND_notify_media(MCIWndInfo *mwi)
 {
     if (mwi->dwStyle & (MCIWNDF_NOTIFYMEDIAA | MCIWNDF_NOTIFYMEDIAW))
@@ -345,16 +375,49 @@ static void MCIWND_notify_media(MCIWndIn
     }
 }
 
+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 WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
     MCIWndInfo *mwi;
 
-    if (wMsg == WM_CREATE)
-        return MCIWND_Create(hWnd, (CREATESTRUCTW *)lParam);
+    TRACE("%p %04x %08x %08lx\n", hWnd, wMsg, wParam, lParam);
 
     mwi = (MCIWndInfo*)GetWindowLongW(hWnd, 0);
     if (!mwi)
+    {
+        if (wMsg == WM_CREATE)
+            return MCIWND_Create(hWnd, (CREATESTRUCTW *)lParam);
+
         return DefWindowProcW(hWnd, wMsg, wParam, lParam);
+    }
 
     switch (wMsg)
     {
@@ -362,11 +425,14 @@ static LRESULT WINAPI MCIWndProc(HWND hW
         if (mwi->uTimer)
             KillTimer(hWnd, mwi->uTimer);
 
-        SendMessageW(hWnd, MCI_CLOSE, 0, 0);
+        if (mwi->mci)
+            SendMessageW(hWnd, MCI_CLOSE, 0, 0);
 
-        if (mwi->lpName)
-            HeapFree(GetProcessHeap(), 0, mwi->lpName);
         HeapFree(GetProcessHeap(), 0, mwi);
+
+        DestroyWindow(GetDlgItem(hWnd, CTL_MENU));
+        DestroyWindow(GetDlgItem(hWnd, CTL_PLAYSTOP));
+        DestroyWindow(GetDlgItem(hWnd, CTL_TRACKBAR));
         return 0;
 
     case WM_PAINT:
@@ -374,38 +440,46 @@ static LRESULT WINAPI MCIWndProc(HWND hW
             HDC hdc;
             PAINTSTRUCT ps;
 
-            hdc = (wParam) ? (HDC)wParam : BeginPaint(mwi->hWnd, &ps);
+            hdc = (wParam) ? (HDC)wParam : BeginPaint(hWnd, &ps);
             /* something to do ? */
-            if (!wParam) EndPaint(mwi->hWnd, &ps);
+            if (!wParam) EndPaint(hWnd, &ps);
             return 1;
         }
 
     case WM_COMMAND:
         return MCIWND_Command(mwi, wParam, lParam);
 
+    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_Timer(mwi);
+        MCIWND_UpdateState(mwi);
         return 0;
 
     case WM_SIZE:
         {
-            MCIWND_NOTIFY_SIZE(mwi);
-
-            if (wParam == SIZE_MINIMIZED) return 0;
-
             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);
+
+            MCIWND_NOTIFY_SIZE(mwi);
             return 0;
         }
 
     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;
         }
@@ -413,6 +487,22 @@ static LRESULT WINAPI MCIWndProc(HWND hW
     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)
             {
@@ -420,83 +510,97 @@ static LRESULT WINAPI MCIWndProc(HWND hW
                 mwi->uTimer = 0;
             }
 
-            if (lParam)
+            hCursor = LoadCursorW(0, (LPWSTR)IDC_WAIT);
+            hCursor = SetCursor(hCursor);
+
+            mci_open.lpstrElementName = (LPWSTR)lParam;
+            wsprintfW(aliasW, formatW, (int)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)
             {
-                HCURSOR hCursor;
-                MCI_OPEN_PARMSW mci_open;
-                MCI_GETDEVCAPS_PARMS mci_devcaps;
-
-                hCursor = LoadCursorW(0, (LPWSTR)IDC_WAIT);
-                hCursor = SetCursor(hCursor);
-
-                mci_open.lpstrElementName = (LPWSTR)lParam;
-                mwi->lasterror = mciSendCommandW(mwi->mci, MCI_OPEN,
-                                                 MCI_OPEN_ELEMENT | MCI_WAIT,
-                                                 (DWORD_PTR)&mci_open);
-                SetCursor(hCursor);
+                /* FIXME: get the caption from resources */
+                static const WCHAR caption[] = {'M','C','I',' ','E','r','r','o','r',0};
+                WCHAR error_str[MAXERRORLENGTH];
 
-                if (mwi->lasterror)
-                {
-                    /* 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;
+            }
 
-                    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 = (int)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;
 
-                mwi->mci = mci_open.wDeviceID;
-                mwi->lpName = HeapAlloc(GetProcessHeap(), 0, (strlenW((LPWSTR)lParam) + 1) * sizeof(WCHAR));
-                strcpyW(mwi->lpName, (LPWSTR)lParam);
-
-                mci_devcaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
-                mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
-                                                 MCI_GETDEVCAPS_ITEM,
-                                                 (DWORD_PTR)&mci_devcaps);
+                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;
                 }
+            }
 
-                mwi->dev_type = mci_devcaps.dwReturn;
-
-                if (mwi->dev_type == MCI_DEVTYPE_DIGITAL_VIDEO)
-                {
-                    MCI_DGV_WINDOW_PARMSW mci_window;
+            if (SendMessageW(hWnd, MCIWNDM_GET_DEST, 0, (LPARAM)&rc) == 0)
+            {
+                mwi->size.cx = rc.right - rc.left;
+                mwi->size.cy = rc.bottom - rc.top;
 
-                    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;
-                    }
-                }
+                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);
             }
-
-            if (SendMessageW(hWnd, MCIWNDM_GET_DEST, 0, (LPARAM)&rc) != 0)
+            else
             {
                 GetClientRect(hWnd, &rc);
                 rc.bottom = rc.top;
             }
 
-            AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
             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);
+                         rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 
             SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L);
-            SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1L, SendMessageW(mwi->hWnd, MCIWNDM_GETLENGTH, 0, 0));
-            SetTimer(hWnd, 1, 500, NULL);
+            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)
@@ -507,6 +611,9 @@ end_of_mci_open:
     case MCIWNDM_GETDEVICEID:
         return mwi->mci;
 
+    case MCIWNDM_GETALIAS:
+        return mwi->alias;
+
     case MCIWNDM_GET_SOURCE:
         {
             MCI_DGV_RECT_PARMS mci_rect;
@@ -561,7 +668,7 @@ end_of_mci_open:
 
             mci_put.rc = *(RECT *)lParam;
             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
-                                             MCI_DGV_PUT_DESTINATION,
+                                             MCI_DGV_PUT_DESTINATION | MCI_DGV_RECT,
                                              (DWORD_PTR)&mci_put);
             if (mwi->lasterror)
             {
@@ -617,15 +724,37 @@ end_of_mci_open:
         {
             MCI_STATUS_PARMS mci_status;
 
+            /* 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)
-            {
-                MCIWND_NOTIFY_ERROR(mwi);
                 return 0;
-            }
+
             return mci_status.dwReturn;
         }
 
@@ -634,6 +763,33 @@ end_of_mci_open:
         {
             MCI_STATUS_PARMS mci_status;
 
+            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,
@@ -644,6 +800,26 @@ end_of_mci_open:
             return mci_status.dwReturn;
         }
 
+    case MCIWNDM_PLAYFROM:
+        {
+            MCI_PLAY_PARMS mci_play;
+
+            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;
@@ -651,20 +827,67 @@ end_of_mci_open:
             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);
+                                             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_RETURNSTRINGA:
+
+    case MCIWNDM_PLAYREVERSE:
+        {
+            MCI_PLAY_PARMS mci_play;
+            DWORD flags = MCI_NOTIFY;
+
+            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);
         return mwi->lasterror;
 
-    case MCIWNDM_RETURNSTRINGW:
+    case MCIWNDM_GETERRORW:
         mciGetErrorStringW(mwi->lasterror, (LPWSTR)lParam, wParam);
         return mwi->lasterror;
 
@@ -672,27 +895,292 @@ end_of_mci_open:
         mwi->hwndOwner = (HWND)wParam;
         return 0;
 
-    case MCI_PLAY:
+    case MCIWNDM_SENDSTRINGA:
         {
-            LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
-            return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end);
+            UNICODE_STRING stringW;
+            RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
+            lParam = (LPARAM)stringW.Buffer;
         }
+        /* fall through */
+    case MCIWNDM_SENDSTRINGW:
+        {
+            WCHAR *cmdW, *p;
 
-    case MCI_STOP:
+            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);
+        return mwi->lasterror;
+
+    case MCIWNDM_RETURNSTRINGW:
+        strncpyW((LPWSTR)lParam, mwi->return_string, wParam);
+        return mwi->lasterror;
+
+    case MCIWNDM_SETTIMERS:
+        mwi->active_timer = (WORD)wParam;
+        mwi->inactive_timer = (WORD)lParam;
+        return 0;
+
+    case MCIWNDM_SETACTIVETIMER:
+        mwi->active_timer = (WORD)wParam;
+        return 0;
+
+    case MCIWNDM_SETINACTIVETIMER:
+        mwi->inactive_timer = (WORD)wParam;
+        return 0;
+
+    case MCIWNDM_GETACTIVETIMER:
+        return mwi->active_timer;
+
+    case MCIWNDM_GETINACTIVETIMER:
+        return mwi->inactive_timer;
+
+    case MCIWNDM_CHANGESTYLES:
+        /* 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:
+        return mwi->dwStyle & 0xffff;
+
+    case MCIWNDM_GETDEVICEA:
         {
-            MCI_GENERIC_PARMS mci_generic;
+            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);
+            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);
+            return 0;
+        }
+
+    case MCIWNDM_VALIDATEMEDIA:
+        if (mwi->mci)
+        {
+            SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
+            SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
+        }
+        return 0;
+
+    case MCIWNDM_GETFILENAMEA:
+        if (mwi->lpName)
+            WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, (LPSTR)lParam, wParam, NULL, NULL);
+        return 0;
 
-            mci_generic.dwCallback = 0;
-            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STOP, 0, (DWORD_PTR)&mci_generic);
+    case MCIWNDM_GETFILENAMEW:
+        if (mwi->lpName)
+            strncpyW((LPWSTR)lParam, mwi->lpName, wParam);
+        return 0;
+
+    case MCIWNDM_GETTIMEFORMATA:
+    case MCIWNDM_GETTIMEFORMATW:
+        {
+            MCI_STATUS_PARMS mci_status;
+
+            /* 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;
+
+            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;
+
+            if (mwi->mci)
             {
-                MCIWND_NOTIFY_ERROR(mwi);
-                return mwi->lasterror;
+                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);
             }
+
+            if (wMsg == MCIWNDM_SETTIMEFORMATA)
+                HeapFree(GetProcessHeap(), 0, (void *)lParam);
+
+            /* 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));
             return 0;
         }
 
+    case MCIWNDM_CAN_PLAY:
+        if (mwi->mci)
+            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_PLAY);
+        return 0;
+
+    case MCIWNDM_CAN_RECORD:
+        if (mwi->mci)
+            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_RECORD);
+        return 0;
+
+    case MCIWNDM_CAN_SAVE:
+        if (mwi->mci)
+            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_SAVE);
+        return 0;
+
+    case MCIWNDM_CAN_EJECT:
+        if (mwi->mci)
+            return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_EJECT);
+        return 0;
+
+    case MCIWNDM_CAN_WINDOW:
+        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:
+        if (mwi->hdrv)
+            return SendDriverMessage(mwi->hdrv, DRV_QUERYCONFIGURE, 0, 0);
+        return 0;
+
+    case MCIWNDM_SETZOOM:
+        mwi->zoom = lParam;
+
+        if (mwi->mci)
+        {
+            RECT rc;
+
+            SetRectEmpty(&rc);
+            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);
+
+            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:
+        return mwi->zoom;
+
+    case MCIWNDM_EJECT:
+        {
+            MCI_SET_PARMS mci_set;
+
+            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SET,
+                                             MCI_SET_DOOR_OPEN | MCI_NOTIFY,
+                                             (DWORD_PTR)&mci_set);
+            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:
         {
             MCI_SEEK_PARMS mci_seek;
@@ -721,25 +1209,106 @@ end_of_mci_open:
 
     case MCI_CLOSE:
         {
+            RECT rc;
             MCI_GENERIC_PARMS mci_generic;
 
-            mci_generic.dwCallback = 0;
-            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE, 0, (DWORD_PTR)&mci_generic);
+            if (mwi->hdrv)
+            {
+                CloseDriver(mwi->hdrv, 0, 0);
+                mwi->hdrv = 0;
+            }
 
-            if (mwi->lasterror)
+            if (mwi->mci)
             {
-                MCIWND_NOTIFY_ERROR(mwi);
-                return mwi->lasterror;
+                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;
+
+            if (mwi->lpName)
+            {
+                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_STEP:
+    case MCI_STOP:
+    case MCI_RESUME:
+        return mci_generic_command(mwi, wMsg);
+
+    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) && (wMsg < WM_APP))
+    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);
 }
diff -u cvs/hq/wine/include/vfw.h wine/include/vfw.h
--- cvs/hq/wine/include/vfw.h   2003-12-16 16:45:53.000000000 +0800
+++ wine/include/vfw.h  2003-12-30 23:28:23.000000000 +0800
@@ -1290,7 +1290,7 @@ BOOL WINAPI GetSaveFileNamePreviewW(LPOP
 #define AVIERR_USERABORT       MAKE_AVIERR(198)
 #define AVIERR_ERROR           MAKE_AVIERR(199)
 
-BOOL VFWAPIV MCIWndRegisterClass(HINSTANCE);
+BOOL VFWAPIV MCIWndRegisterClass(void);
 
 HWND VFWAPIV MCIWndCreateA(HWND, HINSTANCE, DWORD, LPCSTR);
 HWND VFWAPIV MCIWndCreateW(HWND, HINSTANCE, DWORD, LPCWSTR);






More information about the wine-patches mailing list