Add support for some other MCI_ commands and implement mciSendCommandW

Dmitry Timoshkov dmitry at baikal.ru
Wed Dec 31 00:30:54 CST 2003


"Alexandre Julliard" <julliard at winehq.org> wrote:

> This is not thread-safe; if you need to know why the class creation
> failed you should check the last error returned from RegisterClassW.

Well, native msvfw32.dll does exactly that. Anyway, here is
an updated patch.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add Unicode->ANSI MCI message mapping, implement mciSendCommandW,
    fix a bug with a window creation belonging to another hInstance,
    add support for MCI_WINDOW command in mciavi.drv, add support
    for MCI_PLAY and MCI_STOP in the MCIWndClass implementation.

diff -u cvs/hq/wine/dlls/msvideo/mciwnd.c wine/dlls/msvideo/mciwnd.c
--- cvs/hq/wine/dlls/msvideo/mciwnd.c   2003-12-16 16:45:47.000000000 +0800
+++ wine/dlls/msvideo/mciwnd.c  2003-12-31 14:19:02.000000000 +0800
@@ -60,7 +60,7 @@ typedef struct
         SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)(info)->hWnd, (LPARAM)SendMessageW((info)->hWnd, MCIWNDM_GETMODEW, 0, 0))
 
 #define MCIWND_NOTIFY_SIZE(info) \
-    if (mwi->dwStyle & MCIWNDF_NOTIFYSIZE) \
+    if ((info)->dwStyle & MCIWNDF_NOTIFYSIZE) \
         SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYSIZE, (WPARAM)(info)->hWnd, 0);
 
 #define MCIWND_NOTIFY_ERROR(info) \
@@ -84,7 +84,13 @@ BOOL VFWAPIV MCIWndRegisterClass(HINSTAN
 {
     WNDCLASSW wc;
 
-    wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC;
+    /* 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*);
@@ -95,7 +101,10 @@ BOOL VFWAPIV MCIWndRegisterClass(HINSTAN
     wc.lpszMenuName = NULL;
     wc.lpszClassName = mciWndClassW;
 
-    return RegisterClassW(&wc);
+    if (RegisterClassW(&wc)) return TRUE;
+    if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE;
+
+    return FALSE;
 }
 
 /***********************************************************************
@@ -189,7 +198,7 @@ static void MCIWND_UpdateText(MCIWndInfo
             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;
+            case MCI_MODE_SEEK: strcatW(buffer, seekingW); break;
             default: strcatW(buffer, unknownW); break;
         }
     }
@@ -394,7 +403,6 @@ static LRESULT WINAPI MCIWndProc(HWND hW
         MCIWND_NOTIFY_MODE(mwi);
         return 0;
 
-
     case MCIWNDM_OPENA:
         {
             UNICODE_STRING nameW;
@@ -447,13 +455,9 @@ static LRESULT WINAPI MCIWndProc(HWND hW
                 mci_devcaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
                 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
                                                  MCI_GETDEVCAPS_ITEM,
-                                                (DWORD_PTR)&mci_devcaps);
+                                                 (DWORD_PTR)&mci_devcaps);
                 if (mwi->lasterror)
                 {
-                    WCHAR error_str[MAXERRORLENGTH];
-
-                    mciGetErrorStringW(mwi->lasterror, error_str, MAXERRORLENGTH);
-
                     MCIWND_NOTIFY_ERROR(mwi);
                     goto end_of_mci_open;
                 }
@@ -486,10 +490,8 @@ static LRESULT WINAPI MCIWndProc(HWND hW
             if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
                 rc.bottom += 32; /* add the height of the playbar */
             SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
-                rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER);
+                rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 
-            if (mwi->dwStyle & MCIWNDF_NOOPEN)
-                ShowWindow(mwi->hWnd, SW_SHOW);
             MCIWND_NOTIFY_MEDIA(mwi);
 
             SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L);
@@ -670,6 +672,27 @@ end_of_mci_open:
         mwi->hwndOwner = (HWND)wParam;
         return 0;
 
+    case MCI_PLAY:
+        {
+            LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
+            return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end);
+        }
+
+    case MCI_STOP:
+        {
+            MCI_GENERIC_PARMS mci_generic;
+
+            mci_generic.dwCallback = 0;
+            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STOP, 0, (DWORD_PTR)&mci_generic);
+
+            if (mwi->lasterror)
+            {
+                MCIWND_NOTIFY_ERROR(mwi);
+                return mwi->lasterror;
+            }
+            return 0;
+        }
+
     case MCI_SEEK:
         {
             MCI_SEEK_PARMS mci_seek;
@@ -697,15 +720,19 @@ end_of_mci_open:
         }
 
     case MCI_CLOSE:
-        if (mwi->mci)
         {
             MCI_GENERIC_PARMS mci_generic;
 
             mci_generic.dwCallback = 0;
-            mciSendCommandW(mwi->mci, MCI_CLOSE, 0, (DWORD_PTR)&mci_generic);
-            mwi->mci = 0;
+            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE, 0, (DWORD_PTR)&mci_generic);
+
+            if (mwi->lasterror)
+            {
+                MCIWND_NOTIFY_ERROR(mwi);
+                return mwi->lasterror;
+            }
+            return 0;
         }
-        return 0;
     }
 
     if ((wMsg >= WM_USER) && (wMsg < WM_APP))
diff -u cvs/hq/wine/dlls/winmm/mciavi/info.c wine/dlls/winmm/mciavi/info.c
--- cvs/hq/wine/dlls/winmm/mciavi/info.c        2003-10-10 22:05:33.000000000 +0900
+++ wine/dlls/winmm/mciavi/info.c       2003-12-31 13:59:04.000000000 +0800
@@ -401,8 +401,8 @@ DWORD       MCIAVI_mciStatus(UINT wDevID, DWOR
            TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn);
            break;
        case MCI_DGV_STATUS_HWND:
-           lpParms->dwReturn = (DWORD)wma->hWnd;
-           TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWnd);
+           lpParms->dwReturn = (DWORD)wma->hWndPaint;
+           TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint);
            break;
 #if 0
        case MCI_DGV_STATUS_KEY_COLOR:
diff -u cvs/hq/wine/dlls/winmm/mciavi/mciavi.c wine/dlls/winmm/mciavi/mciavi.c
--- cvs/hq/wine/dlls/winmm/mciavi/mciavi.c      2003-07-01 16:18:00.000000000 +0900
+++ wine/dlls/winmm/mciavi/mciavi.c     2003-12-31 13:59:04.000000000 +0800
@@ -135,7 +135,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, 
 static DWORD   MCIAVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
 {
     WINE_MCIAVI*       wma;
-    static WCHAR       mciAviWStr[] = {'M','C','I','A','V','I',0};
+    static const WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0};
 
     if (!modp) return 0xFFFFFFFF;
 
@@ -356,7 +356,7 @@ static      DWORD   MCIAVI_mciPlay(UINT wDevID,
     if (wma == NULL)           return MCIERR_INVALID_DEVICE_ID;
 
     if (!wma->hFile)           return MCIERR_FILE_NOT_FOUND;
-    if (!wma->hWnd)            return MCIERR_NO_WINDOW;
+    if (!wma->hWndPaint)       return MCIERR_NO_WINDOW;
 
     wma->dwStatus = MCI_MODE_PLAY;
 
@@ -365,7 +365,7 @@ static      DWORD   MCIAVI_mciPlay(UINT wDevID,
                                    (DWORD)lpParms, sizeof(MCI_PLAY_PARMS));
     }
 
-    ShowWindow(wma->hWnd, SW_SHOW);
+    ShowWindow(wma->hWndPaint, SW_SHOW);
 
     dwFromFrame = wma->dwCurrVideoFrame;
     dwToFrame = wma->dwPlayableVideoFrames - 1;
diff -u cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c wine/dlls/winmm/mciavi/mmoutput.c
--- cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c    2003-11-22 21:56:11.000000000 +0800
+++ wine/dlls/winmm/mciavi/mmoutput.c   2003-12-31 13:59:04.000000000 +0800
@@ -575,9 +575,9 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm
        return FALSE;
     }
 
-    if (IsWindowVisible(wma->hWnd) && (hDC = GetDC(wma->hWnd)) != 0) {
+    if (IsWindowVisible(wma->hWndPaint) && (hDC = GetDC(wma->hWndPaint)) != 0) {
        MCIAVI_PaintFrame(wma, hDC);
-       ReleaseDC(wma->hWnd, hDC);
+       ReleaseDC(wma->hWndPaint, hDC);
     }
 
     LeaveCriticalSection(&wma->cs);
diff -u cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h wine/dlls/winmm/mciavi/private_mciavi.h
--- cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h      2003-09-09 15:36:29.000000000 +0900
+++ wine/dlls/winmm/mciavi/private_mciavi.h     2003-12-31 13:59:04.000000000 +0800
@@ -72,7 +72,7 @@ typedef struct {
     HANDLE             hEvent;                 /* for synchronization */
     DWORD              dwEventCount;           /* for synchronization */
     /* data for play back */
-    HWND               hWnd;
+    HWND               hWnd, hWndPaint;
     DWORD              dwCurrVideoFrame;       /* video frame to display and current position */
     DWORD              dwCurrAudioBlock;       /* current audio block being played */
     /* data for the background mechanism */
diff -u cvs/hq/wine/dlls/winmm/mciavi/wnd.c wine/dlls/winmm/mciavi/wnd.c
--- cvs/hq/wine/dlls/winmm/mciavi/wnd.c 2003-10-04 15:30:08.000000000 +0900
+++ wine/dlls/winmm/mciavi/wnd.c        2003-12-31 13:59:04.000000000 +0800
@@ -87,6 +87,7 @@ BOOL    MCIAVI_CreateWindow(WINE_MCIAVI*
     HWND       hParent = 0;
     DWORD      dwStyle = WS_OVERLAPPEDWINDOW;
     int                p = CW_USEDEFAULT;
+    RECT rc;
 
     /* what should be done ? */
     if (wma->hWnd) return TRUE;
@@ -106,11 +107,17 @@ BOOL    MCIAVI_CreateWindow(WINE_MCIAVI*
     if (dwFlags & MCI_DGV_OPEN_WS)     dwStyle = lpOpenParms->dwStyle;
     if (dwStyle & WS_CHILD)            p = 0;
 
+    rc.left = p;
+    rc.top = p;
+    rc.right = (wma->hic ? wma->outbih : wma->inbih)->biWidth;
+    rc.bottom = (wma->hic ? wma->outbih : wma->inbih)->biHeight;
+    AdjustWindowRect(&rc, dwStyle, FALSE);
+
     wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player",
-                             dwStyle, p, p,
-                             (wma->hic ? wma->outbih : wma->inbih)->biWidth,
-                             (wma->hic ? wma->outbih : wma->inbih)->biHeight,
+                             dwStyle, rc.left, rc.top,
+                             rc.right, rc.bottom,
                              hParent, 0, MCIAVI_hInstance, wma);
+    wma->hWndPaint = wma->hWnd;
     return (BOOL)wma->hWnd;
 }
 
@@ -193,7 +200,7 @@ DWORD       MCIAVI_mciWhere(UINT wDevID, DWORD
     }
     if (dwFlags & MCI_DGV_WHERE_WINDOW) {
        x = "Window";
-       GetClientRect(wma->hWnd, &lpParms->rc);
+       GetClientRect(wma->hWndPaint, &lpParms->rc);
     }
     TRACE("%s -> (%ld,%ld,%ld,%ld)\n",
          x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom);
@@ -214,20 +221,18 @@ DWORD     MCIAVI_mciWindow(UINT wDevID, DWOR
     if (wma == NULL)           return MCIERR_INVALID_DEVICE_ID;
 
     if (dwFlags & MCI_DGV_WINDOW_HWND) {
-       FIXME("Setting hWnd to %08lx\n", (DWORD)lpParms->hWnd);
-#if 0
-       if (wma->hWnd) DestroyWindow(wma->hWnd);
-       /* is the window to be subclassed ? */
-       wma->hWnd = lpParms->hWnd;
-#endif
+       TRACE("Setting hWnd to %p\n", lpParms->hWnd);
+       if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE);
+       wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd;
+        InvalidateRect(wma->hWndPaint, NULL, FALSE);
     }
     if (dwFlags & MCI_DGV_WINDOW_STATE) {
        TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
-       ShowWindow(wma->hWnd, lpParms->nCmdShow);
+       ShowWindow(wma->hWndPaint, lpParms->nCmdShow);
     }
     if (dwFlags & MCI_DGV_WINDOW_TEXT) {
        TRACE("Setting caption to '%s'\n", lpParms->lpstrText);
-       SetWindowTextA(wma->hWnd, lpParms->lpstrText);
+       SetWindowTextA(wma->hWndPaint, lpParms->lpstrText);
     }
 
     return 0;
diff -u cvs/hq/wine/dlls/winmm/mci.c wine/dlls/winmm/mci.c
--- cvs/hq/wine/dlls/winmm/mci.c        2003-10-20 13:17:18.000000000 +0900
+++ wine/dlls/winmm/mci.c       2003-12-31 13:59:03.000000000 +0800
@@ -1157,7 +1157,7 @@ BOOL WINAPI mciFreeCommandResource(UINT 
 /**************************************************************************
  *                     MCI_SendCommandFrom32                   [internal]
  */
-DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD              dwRet = MCIERR_INVALID_DEVICE_ID;
     LPWINE_MCIDRIVER   wmd = MCI_GetDriver(wDevID);
@@ -1192,7 +1192,7 @@ DWORD MCI_SendCommandFrom32(UINT wDevID,
 /**************************************************************************
  *                     MCI_SendCommandFrom16                   [internal]
  */
-DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD MCI_SendCommandFrom16(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD              dwRet = MCIERR_INVALID_DEVICE_ID;
     LPWINE_MCIDRIVER   wmd = MCI_GetDriver(wDevID);
diff -u cvs/hq/wine/dlls/winmm/winmm.c wine/dlls/winmm/winmm.c
--- cvs/hq/wine/dlls/winmm/winmm.c      2003-12-09 22:42:50.000000000 +0800
+++ wine/dlls/winmm/winmm.c     2003-12-31 13:59:04.000000000 +0800
@@ -42,6 +42,7 @@
 #include "winternl.h"
 #include "winemm.h"
 #include "wownt32.h"
+#include "heap.h"
 
 #include "wine/debug.h"
 
@@ -707,20 +708,19 @@ UINT WINAPI auxOutMessage(UINT uDeviceID
 /**************************************************************************
  *                             mciGetErrorStringW              [WINMM.@]
  */
-BOOL WINAPI mciGetErrorStringW(DWORD wError, LPWSTR lpstrBuffer, UINT uLength)
+BOOL WINAPI mciGetErrorStringW(MCIERROR wError, LPWSTR lpstrBuffer, UINT uLength)
 {
-    LPSTR      bufstr = HeapAlloc(GetProcessHeap(), 0, uLength);
-    BOOL       ret = mciGetErrorStringA(wError, bufstr, uLength);
+    char       bufstr[MAXERRORLENGTH];
+    BOOL       ret = mciGetErrorStringA(wError, bufstr, MAXERRORLENGTH);
 
     MultiByteToWideChar( CP_ACP, 0, bufstr, -1, lpstrBuffer, uLength );
-    HeapFree(GetProcessHeap(), 0, bufstr);
     return ret;
 }
 
 /**************************************************************************
  *                             mciGetErrorStringA              [WINMM.@]
  */
-BOOL WINAPI mciGetErrorStringA(DWORD dwError, LPSTR lpstrBuffer, UINT uLength)
+BOOL WINAPI mciGetErrorStringA(MCIERROR dwError, LPSTR lpstrBuffer, UINT uLength)
 {
     BOOL               ret = FALSE;
 
@@ -738,18 +738,18 @@ BOOL WINAPI mciGetErrorStringA(DWORD dwE
 /**************************************************************************
  *                     mciDriverNotify                         [WINMM.@]
  */
-BOOL WINAPI mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
+BOOL WINAPI mciDriverNotify(HWND hWndCallBack, MCIDEVICEID wDevID, UINT wStatus)
 {
 
     TRACE("(%p, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
 
-    return PostMessageA(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
+    return PostMessageW(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
 }
 
 /**************************************************************************
  *                     mciGetDriverData                        [WINMM.@]
  */
-DWORD WINAPI mciGetDriverData(UINT uDeviceID)
+DWORD WINAPI mciGetDriverData(MCIDEVICEID uDeviceID)
 {
     LPWINE_MCIDRIVER   wmd;
 
@@ -768,7 +768,7 @@ DWORD WINAPI mciGetDriverData(UINT uDevi
 /**************************************************************************
  *                     mciSetDriverData                        [WINMM.@]
  */
-BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD data)
+BOOL WINAPI mciSetDriverData(MCIDEVICEID uDeviceID, DWORD data)
 {
     LPWINE_MCIDRIVER   wmd;
 
@@ -788,7 +788,7 @@ BOOL WINAPI mciSetDriverData(UINT uDevic
 /**************************************************************************
  *                             mciSendCommandA                 [WINMM.@]
  */
-DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD WINAPI mciSendCommandA(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD      dwRet;
 
@@ -801,14 +801,177 @@ DWORD WINAPI mciSendCommandA(UINT wDevID
     return dwRet;
 }
 
+static int MCI_MapMsgWtoA(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
+{
+    switch(msg)
+    {
+    case MCI_CLOSE:
+    case MCI_PLAY:
+    case MCI_SEEK:
+    case MCI_STOP:
+    case MCI_PAUSE:
+    case MCI_GETDEVCAPS:
+    case MCI_SPIN:
+    case MCI_SET:
+    case MCI_STEP:
+    case MCI_RECORD:
+    case MCI_BREAK:
+    case MCI_SOUND:
+    case MCI_STATUS:
+    case MCI_CUE:
+    case MCI_REALIZE:
+    case MCI_PUT:
+    case MCI_WHERE:
+    case MCI_FREEZE:
+    case MCI_UNFREEZE:
+    case MCI_CUT:
+    case MCI_COPY:
+    case MCI_PASTE:
+    case MCI_UPDATE:
+    case MCI_RESUME:
+    case MCI_DELETE:
+        return 0;
+
+    case MCI_OPEN:
+        {
+            MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*dwParam2;
+            MCI_OPEN_PARMSA *mci_openA;
+            DWORD_PTR *ptr;
+
+            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_openA) + sizeof(DWORD_PTR));
+            if (!ptr) return -1;
+
+            *ptr++ = *dwParam2; /* save the previous pointer */
+            *dwParam2 = (DWORD_PTR)ptr;
+            mci_openA = (MCI_OPEN_PARMSA *)ptr;
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_openA->dwCallback = mci_openW->dwCallback;
+
+            if (dwParam1 & MCI_OPEN_TYPE)
+            {
+                if (dwParam1 & MCI_OPEN_TYPE_ID)
+                    mci_openA->lpstrDeviceType = (LPSTR)mci_openW->lpstrDeviceType;
+                else
+                    mci_openA->lpstrDeviceType = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_openW->lpstrDeviceType);
+            }
+            if (dwParam1 & MCI_OPEN_ELEMENT)
+            {
+                if (dwParam1 & MCI_OPEN_ELEMENT_ID)
+                    mci_openA->lpstrElementName = (LPSTR)mci_openW->lpstrElementName;
+                else
+                    mci_openA->lpstrElementName = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_openW->lpstrElementName);
+            }
+            if (dwParam1 & MCI_OPEN_ALIAS)
+                mci_openA->lpstrAlias = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_openW->lpstrAlias);
+        }
+        return 1;
+
+    case MCI_WINDOW:
+        if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
+        {
+            MCI_ANIM_WINDOW_PARMSW *mci_windowW = (MCI_ANIM_WINDOW_PARMSW *)*dwParam2;
+            MCI_ANIM_WINDOW_PARMSA *mci_windowA;
+
+            mci_windowA = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_windowA));
+            if (!mci_windowA) return -1;
+
+            *dwParam2 = (DWORD_PTR)mci_windowA;
+
+            mci_windowA->lpstrText = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_windowW->lpstrText);
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_windowA->dwCallback = mci_windowW->dwCallback;
+            if (dwParam1 & MCI_ANIM_WINDOW_HWND)
+                mci_windowA->hWnd = mci_windowW->hWnd;
+            if (dwParam1 & MCI_ANIM_WINDOW_STATE)
+                mci_windowA->nCmdShow = mci_windowW->nCmdShow;
+
+            return 1;
+        }
+        return 0;
+
+    case MCI_INFO:
+    case MCI_SYSINFO:
+    case MCI_SAVE:
+    case MCI_LOAD:
+    case MCI_ESCAPE:
+    default:
+        FIXME("Message 0x%04x needs translation\n", msg);
+        return -1;
+    }
+    return 0;
+}
+
+static void MCI_UnmapMsgWtoA(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+{
+    switch(msg)
+    {
+    case MCI_OPEN:
+        {
+            DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
+            MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*ptr;
+            MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA *)(ptr + 1);
+
+            mci_openW->wDeviceID = mci_openA->wDeviceID;
+
+            if (dwParam1 & MCI_OPEN_TYPE)
+            {
+                if (!(dwParam1 & MCI_OPEN_TYPE_ID))
+                    HeapFree(GetProcessHeap(), 0, mci_openA->lpstrDeviceType);
+            }
+            if (dwParam1 & MCI_OPEN_ELEMENT)
+            {
+                if (!(dwParam1 & MCI_OPEN_ELEMENT_ID))
+                    HeapFree(GetProcessHeap(), 0, mci_openA->lpstrElementName);
+            }
+            if (dwParam1 & MCI_OPEN_ALIAS)
+                HeapFree(GetProcessHeap(), 0, mci_openA->lpstrAlias);
+            HeapFree(GetProcessHeap(), 0, ptr);
+        }
+        break;
+
+    case MCI_WINDOW:
+        if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
+        {
+            MCI_ANIM_WINDOW_PARMSA *mci_windowA = (MCI_ANIM_WINDOW_PARMSA *)dwParam2;
+
+            HeapFree(GetProcessHeap(), 0, (void *)mci_windowA->lpstrText);
+            HeapFree(GetProcessHeap(), 0, mci_windowA);
+        }
+        break;
+
+    default:
+        FIXME("Message 0x%04x needs unmapping\n", msg);
+        break;
+    }
+}
+
+
 /**************************************************************************
  *                             mciSendCommandW                 [WINMM.@]
+ *
+ * FIXME: we should do the things other way around, but since our
+ * MM subsystem is not unicode aware...
  */
-DWORD WINAPI mciSendCommandW(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD WINAPI mciSendCommandW(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
-    FIXME("(%08x, %s, %08lx, %08lx): stub\n",
+    DWORD ret;
+    int mapped;
+
+    TRACE("(%08x, %s, %08lx, %08lx)\n",
          wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
-    return MCIERR_UNSUPPORTED_FUNCTION;
+
+    mapped = MCI_MapMsgWtoA(wMsg, dwParam1, &dwParam2);
+    if (mapped == -1)
+    {
+        FIXME("message %04x mapping failed\n", wMsg);
+        return MMSYSERR_NOMEM;
+    }
+    ret = mciSendCommandA(wDevID, wMsg, dwParam1, dwParam2);
+    if (mapped)
+        MCI_UnmapMsgWtoA(wMsg, dwParam1, dwParam2);
+    return ret;
 }
 
 /**************************************************************************
@@ -864,7 +1027,7 @@ UINT WINAPI MCI_DefYieldProc(MCIDEVICEID
 /**************************************************************************
  *                             mciSetYieldProc                 [WINMM.@]
  */
-BOOL WINAPI mciSetYieldProc(UINT uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData)
+BOOL WINAPI mciSetYieldProc(MCIDEVICEID uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData)
 {
     LPWINE_MCIDRIVER   wmd;
 
@@ -897,7 +1060,7 @@ UINT WINAPI mciGetDeviceIDFromElementIDW
 /**************************************************************************
  *                             mciGetYieldProc                 [WINMM.@]
  */
-YIELDPROC WINAPI mciGetYieldProc(UINT uDeviceID, DWORD* lpdwYieldData)
+YIELDPROC WINAPI mciGetYieldProc(MCIDEVICEID uDeviceID, DWORD* lpdwYieldData)
 {
     LPWINE_MCIDRIVER   wmd;
 
@@ -921,7 +1084,7 @@ YIELDPROC WINAPI mciGetYieldProc(UINT uD
 /**************************************************************************
  *                             mciGetCreatorTask               [WINMM.@]
  */
-HTASK WINAPI mciGetCreatorTask(UINT uDeviceID)
+HTASK WINAPI mciGetCreatorTask(MCIDEVICEID uDeviceID)
 {
     LPWINE_MCIDRIVER   wmd;
     HTASK ret = 0;
@@ -935,7 +1098,7 @@ HTASK WINAPI mciGetCreatorTask(UINT uDev
 /**************************************************************************
  *                     mciDriverYield                          [WINMM.@]
  */
-UINT WINAPI mciDriverYield(UINT uDeviceID)
+UINT WINAPI mciDriverYield(MCIDEVICEID uDeviceID)
 {
     LPWINE_MCIDRIVER   wmd;
     UINT               ret = 0;
diff -u cvs/hq/wine/include/mmsystem.h wine/include/mmsystem.h
--- cvs/hq/wine/include/mmsystem.h      2003-09-18 10:44:22.000000000 +0900
+++ wine/include/mmsystem.h     2003-12-31 13:59:04.000000000 +0800
@@ -1407,8 +1407,8 @@ MMRESULT  WINAPI  mmioCreateChunk(HMMIO,MM
 
 typedef UINT (CALLBACK *YIELDPROC)(MCIDEVICEID,DWORD);
 
-DWORD          WINAPI  mciSendCommandA(UINT,UINT,DWORD,DWORD);
-DWORD          WINAPI  mciSendCommandW(UINT,UINT,DWORD,DWORD);
+DWORD          WINAPI  mciSendCommandA(MCIDEVICEID,UINT,DWORD_PTR,DWORD_PTR);
+DWORD          WINAPI  mciSendCommandW(MCIDEVICEID,UINT,DWORD_PTR,DWORD_PTR);
 #define                mciSendCommand WINELIB_NAME_AW(mciSendCommand)
 DWORD          WINAPI  mciSendStringA(LPCSTR,LPSTR,UINT,HWND);
 DWORD          WINAPI  mciSendStringW(LPCWSTR,LPWSTR,UINT,HWND);
@@ -1416,12 +1416,12 @@ DWORD           WINAPI  mciSendStringW(LPCWSTR,LPW
 UINT           WINAPI  mciGetDeviceIDA(LPCSTR);
 UINT           WINAPI  mciGetDeviceIDW(LPCWSTR);
 #define                mciGetDeviceID WINELIB_NAME_AW(mciGetDeviceID)
-BOOL           WINAPI  mciGetErrorStringA(DWORD,LPSTR,UINT);
-BOOL           WINAPI  mciGetErrorStringW(DWORD,LPWSTR,UINT);
+BOOL           WINAPI  mciGetErrorStringA(MCIERROR,LPSTR,UINT);
+BOOL           WINAPI  mciGetErrorStringW(MCIERROR,LPWSTR,UINT);
 #define                mciGetErrorString WINELIB_NAME_AW(mciGetErrorString)
-BOOL           WINAPI  mciSetYieldProc(UINT,YIELDPROC,DWORD);
-HTASK          WINAPI  mciGetCreatorTask(UINT);
-YIELDPROC      WINAPI  mciGetYieldProc(UINT,DWORD*);
+BOOL           WINAPI  mciSetYieldProc(MCIDEVICEID,YIELDPROC,DWORD);
+HTASK          WINAPI  mciGetCreatorTask(MCIDEVICEID);
+YIELDPROC      WINAPI  mciGetYieldProc(MCIDEVICEID,DWORD*);
 
 #define MCIERR_INVALID_DEVICE_ID        (MCIERR_BASE + 1)
 #define MCIERR_UNRECOGNIZED_KEYWORD     (MCIERR_BASE + 3)






More information about the wine-patches mailing list