ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mciwnd.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2000 Eric Pouech
00003  * Copyright 2003 Dmitry Timoshkov
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00018  *
00019  * FIXME:
00020  * Add support for all remaining MCI_ commands and MCIWNDM_ messages.
00021  * Add support for MCIWNDF_RECORD.
00022  */
00023 
00024 #include <stdarg.h>
00025 
00026 #include "windef.h"
00027 #include "winbase.h"
00028 #include "winnls.h"
00029 #include "wingdi.h"
00030 #include "winuser.h"
00031 #include "winternl.h"
00032 #include "vfw.h"
00033 #include "digitalv.h"
00034 #include "commctrl.h"
00035 #include "wine/unicode.h"
00036 #include "wine/debug.h"
00037 
00038 WINE_DEFAULT_DEBUG_CHANNEL(mci);
00039 
00040 extern HMODULE MSVFW32_hModule;
00041 static const WCHAR mciWndClassW[] = {'M','C','I','W','n','d','C','l','a','s','s',0};
00042 
00043 typedef struct
00044 {
00045     DWORD       dwStyle;
00046     MCIDEVICEID mci;
00047     HDRVR       hdrv;
00048     int         alias;
00049     UINT        dev_type;
00050     UINT        mode;
00051     LONG        position;
00052     SIZE        size; /* size of the original frame rect */
00053     int         zoom;
00054     LPWSTR      lpName;
00055     HWND        hWnd, hwndOwner;
00056     UINT        uTimer;
00057     MCIERROR    lasterror;
00058     WCHAR       return_string[128];
00059     WORD        active_timer, inactive_timer;
00060 } MCIWndInfo;
00061 
00062 static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
00063 
00064 #define CTL_PLAYSTOP    0x3200
00065 #define CTL_MENU        0x3201
00066 #define CTL_TRACKBAR    0x3202
00067 
00068 /***********************************************************************
00069  *                MCIWndRegisterClass                [MSVFW32.@]
00070  *
00071  * NOTE: Native always uses its own hInstance
00072  */
00073 BOOL VFWAPIV MCIWndRegisterClass(void)
00074 {
00075     WNDCLASSW wc;
00076 
00077     /* Since we are going to register a class belonging to MSVFW32
00078      * and later we will create windows with a different hInstance
00079      * CS_GLOBALCLASS is needed. And because the second attempt
00080      * to register a global class will fail we need to test whether
00081      * the class was already registered.
00082      */
00083     wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC | CS_GLOBALCLASS;
00084     wc.lpfnWndProc = MCIWndProc;
00085     wc.cbClsExtra = 0;
00086     wc.cbWndExtra = sizeof(MCIWndInfo*);
00087     wc.hInstance = MSVFW32_hModule;
00088     wc.hIcon = 0;
00089     wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDC_ARROW));
00090     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
00091     wc.lpszMenuName = NULL;
00092     wc.lpszClassName = mciWndClassW;
00093 
00094     if (RegisterClassW(&wc)) return TRUE;
00095     if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE;
00096 
00097     return FALSE;
00098 }
00099 
00100 /***********************************************************************
00101  *                MCIWndCreateW                                [MSVFW32.@]
00102  */
00103 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
00104                            DWORD dwStyle, LPCWSTR szFile)
00105 {
00106     TRACE("%p %p %x %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));
00107 
00108     MCIWndRegisterClass();
00109 
00110     if (!hInstance) hInstance = GetModuleHandleW(0);
00111 
00112     if (hwndParent)
00113         dwStyle |= WS_VISIBLE | WS_BORDER /*| WS_CHILD*/;
00114     else
00115         dwStyle |= WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
00116 
00117     return CreateWindowExW(0, mciWndClassW, NULL,
00118                            dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
00119                            0, 0, 300, 0,
00120                            hwndParent, 0, hInstance, (LPVOID)szFile);
00121 }
00122 
00123 /***********************************************************************
00124  *                MCIWndCreate                [MSVFW32.@]
00125  *                MCIWndCreateA                [MSVFW32.@]
00126  */
00127 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
00128                            DWORD dwStyle, LPCSTR szFile)
00129 {
00130     HWND ret;
00131     UNICODE_STRING fileW;
00132 
00133     if (szFile)
00134         RtlCreateUnicodeStringFromAsciiz(&fileW, szFile);
00135     else
00136         fileW.Buffer = NULL;
00137 
00138     ret = MCIWndCreateW(hwndParent, hInstance, dwStyle, fileW.Buffer);
00139 
00140     RtlFreeUnicodeString(&fileW);
00141     return ret;
00142 }
00143 
00144 static inline void MCIWND_notify_mode(MCIWndInfo *mwi)
00145 {
00146     if (mwi->dwStyle & MCIWNDF_NOTIFYMODE)
00147     {
00148         UINT new_mode = SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0);
00149         if (new_mode != mwi->mode)
00150         {
00151             mwi->mode = new_mode;
00152             SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)mwi->hWnd, new_mode);
00153         }
00154     }
00155 }
00156 
00157 static inline void MCIWND_notify_pos(MCIWndInfo *mwi)
00158 {
00159     if (mwi->dwStyle & MCIWNDF_NOTIFYPOS)
00160     {
00161         LONG new_pos = SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 0, 0);
00162         if (new_pos != mwi->position)
00163         {
00164             mwi->position = new_pos;
00165             SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYPOS, (WPARAM)mwi->hWnd, new_pos);
00166         }
00167     }
00168 }
00169 
00170 static inline void MCIWND_notify_size(MCIWndInfo *mwi)
00171 {
00172     if (mwi->dwStyle & MCIWNDF_NOTIFYSIZE)
00173         SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYSIZE, (WPARAM)mwi->hWnd, 0);
00174 }
00175 
00176 static inline void MCIWND_notify_error(MCIWndInfo *mwi)
00177 {
00178     if (mwi->dwStyle & MCIWNDF_NOTIFYERROR)
00179         SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYERROR, (WPARAM)mwi->hWnd, (LPARAM)mwi->lasterror);
00180 }
00181 
00182 static void MCIWND_UpdateState(MCIWndInfo *mwi)
00183 {
00184     WCHAR buffer[1024];
00185 
00186     if (!mwi->mci)
00187     {
00188         /* FIXME: get this from resources */
00189         static const WCHAR no_deviceW[] = {'N','o',' ','D','e','v','i','c','e',0};
00190         SetWindowTextW(mwi->hWnd, no_deviceW);
00191         return;
00192     }
00193 
00194     MCIWND_notify_pos(mwi);
00195 
00196     if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
00197         SendDlgItemMessageW(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, TRUE, mwi->position);
00198 
00199     if (!(mwi->dwStyle & MCIWNDF_SHOWALL))
00200         return;
00201 
00202     if ((mwi->dwStyle & MCIWNDF_SHOWNAME) && mwi->lpName)
00203         strcpyW(buffer, mwi->lpName);
00204     else
00205         *buffer = 0;
00206 
00207     if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
00208     {
00209         static const WCHAR spaceW[] = {' ',0};
00210         static const WCHAR l_braceW[] = {'(',0};
00211 
00212         if (*buffer) strcatW(buffer, spaceW);
00213         strcatW(buffer, l_braceW);
00214     }
00215 
00216     if (mwi->dwStyle & MCIWNDF_SHOWPOS)
00217     {
00218         WCHAR posW[64];
00219 
00220         posW[0] = 0;
00221         SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 64, (LPARAM)posW);
00222         strcatW(buffer, posW);
00223     }
00224 
00225     if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
00226     {
00227         static const WCHAR dashW[] = {' ','-',' ',0};
00228         strcatW(buffer, dashW);
00229     }
00230 
00231     if (mwi->dwStyle & MCIWNDF_SHOWMODE)
00232     {
00233         WCHAR modeW[64];
00234 
00235         modeW[0] = 0;
00236         SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 64, (LPARAM)modeW);
00237         strcatW(buffer, modeW);
00238     }
00239 
00240     if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
00241     {
00242         static const WCHAR r_braceW[] = {')',0};
00243         strcatW(buffer, r_braceW);
00244     }
00245 
00246     TRACE("=> %s\n", debugstr_w(buffer));
00247     SetWindowTextW(mwi->hWnd, buffer);
00248 }
00249 
00250 static LRESULT MCIWND_Create(HWND hWnd, LPCREATESTRUCTW cs)
00251 {
00252     HWND hChld;
00253     MCIWndInfo *mwi;
00254     static const WCHAR buttonW[] = {'b','u','t','t','o','n',0};
00255 
00256     mwi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*mwi));
00257     if (!mwi) return -1;
00258 
00259     SetWindowLongW(hWnd, 0, (LPARAM)mwi);
00260 
00261     mwi->dwStyle = cs->style;
00262     /* There is no need to show stats if there is no caption */
00263     if ((mwi->dwStyle & WS_CAPTION) != WS_CAPTION)
00264         mwi->dwStyle &= ~MCIWNDF_SHOWALL;
00265 
00266     mwi->hWnd = hWnd;
00267     mwi->hwndOwner = cs->hwndParent;
00268     mwi->active_timer = 500;
00269     mwi->inactive_timer = 2000;
00270     mwi->mode = MCI_MODE_NOT_READY;
00271     mwi->position = -1;
00272     mwi->zoom = 100;
00273 
00274     if (!(mwi->dwStyle & MCIWNDF_NOMENU))
00275     {
00276         static const WCHAR menuW[] = {'M','e','n','u',0};
00277 
00278         hChld = CreateWindowExW(0, buttonW, menuW, WS_CHILD|WS_VISIBLE, 32, cs->cy, 32, 32,
00279                                 hWnd, (HMENU)CTL_MENU, cs->hInstance, 0L);
00280         TRACE("Get Button2: %p\n", hChld);
00281     }
00282 
00283     if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
00284     {
00285         INITCOMMONCONTROLSEX init;
00286         static const WCHAR playW[] = {'P','l','a','y',0};
00287 
00288         /* adding the other elements: play/stop button, menu button, status */
00289         hChld = CreateWindowExW(0, buttonW, playW, WS_CHILD|WS_VISIBLE, 0, cs->cy, 32, 32,
00290                                 hWnd, (HMENU)CTL_PLAYSTOP, cs->hInstance, 0L);
00291         TRACE("Get Button1: %p\n", hChld);
00292 
00293         init.dwSize = sizeof(init);
00294         init.dwICC = ICC_BAR_CLASSES;
00295         InitCommonControlsEx(&init);
00296 
00297         hChld = CreateWindowExW(0, TRACKBAR_CLASSW, NULL, WS_CHILD|WS_VISIBLE, 64, cs->cy, cs->cx - 64, 32,
00298                                 hWnd, (HMENU)CTL_TRACKBAR, cs->hInstance, 0L);
00299         TRACE("Get status: %p\n", hChld);
00300     }
00301 
00302     /* This sets the default window size */
00303     SendMessageW(hWnd, MCI_CLOSE, 0, 0);
00304 
00305     if (cs->lpCreateParams)
00306     {
00307         LPARAM lParam;
00308 
00309         /* MCI wnd class is prepared to be embedded as an MDI child window */
00310         if (cs->dwExStyle & WS_EX_MDICHILD)
00311         {
00312             MDICREATESTRUCTW *mdics = cs->lpCreateParams;
00313             lParam = mdics->lParam;
00314         }
00315         else
00316             lParam = (LPARAM)cs->lpCreateParams;
00317 
00318         /* If it's our internal class pointer, file name is a unicode string */
00319         if (cs->lpszClass == mciWndClassW)
00320             SendMessageW(hWnd, MCIWNDM_OPENW, 0, lParam);
00321         else
00322         {
00323             /* Otherwise let's try to figure out what string format is used */
00324             HWND parent = cs->hwndParent;
00325             if (!parent) parent = GetWindow(hWnd, GW_OWNER);
00326 
00327             SendMessageW(hWnd, IsWindowUnicode(parent) ? MCIWNDM_OPENW : MCIWNDM_OPENA, 0, lParam);
00328         }
00329     }
00330 
00331     return 0;
00332 }
00333 
00334 static void MCIWND_ToggleState(MCIWndInfo *mwi)
00335 {
00336     switch (SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0))
00337     {
00338     case MCI_MODE_NOT_READY:
00339     case MCI_MODE_RECORD:
00340     case MCI_MODE_SEEK:
00341     case MCI_MODE_OPEN:
00342         TRACE("Cannot do much...\n");
00343         break;
00344 
00345     case MCI_MODE_PAUSE:
00346         SendMessageW(mwi->hWnd, MCI_RESUME, 0, 0);
00347         break;
00348 
00349     case MCI_MODE_PLAY:
00350         SendMessageW(mwi->hWnd, MCI_PAUSE, 0, 0);
00351         break;
00352 
00353     case MCI_MODE_STOP:
00354         SendMessageW(mwi->hWnd, MCI_STOP, 0, 0);
00355         break;
00356     }
00357 }
00358 
00359 static LRESULT MCIWND_Command(MCIWndInfo *mwi, WPARAM wParam, LPARAM lParam)
00360 {
00361     switch (LOWORD(wParam))
00362     {
00363     case CTL_PLAYSTOP: MCIWND_ToggleState(mwi); break;
00364     case CTL_MENU:
00365     case CTL_TRACKBAR:
00366     default:
00367         FIXME("support for command %04x not implement yet\n", LOWORD(wParam));
00368     }
00369     return 0L;
00370 }
00371 
00372 static void MCIWND_notify_media(MCIWndInfo *mwi)
00373 {
00374     if (mwi->dwStyle & (MCIWNDF_NOTIFYMEDIAA | MCIWNDF_NOTIFYMEDIAW))
00375     {
00376         if (!mwi->lpName)
00377         {
00378             static const WCHAR empty_str[1];
00379             SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)empty_str);
00380         }
00381         else
00382         {
00383             if (mwi->dwStyle & MCIWNDF_NOTIFYANSI)
00384             {
00385                 char *ansi_name;
00386                 int len;
00387 
00388                 len = WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, NULL, 0, NULL, NULL);
00389                 ansi_name = HeapAlloc(GetProcessHeap(), 0, len);
00390                 WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, ansi_name, len, NULL, NULL);
00391 
00392                 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)ansi_name);
00393 
00394                 HeapFree(GetProcessHeap(), 0, ansi_name);
00395             }
00396             else
00397                 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)mwi->lpName);
00398         }
00399     }
00400 }
00401 
00402 static MCIERROR mci_generic_command(MCIWndInfo *mwi, UINT cmd)
00403 {
00404     MCI_GENERIC_PARMS mci_generic;
00405 
00406     mci_generic.dwCallback = 0;
00407     mwi->lasterror = mciSendCommandW(mwi->mci, cmd, 0, (DWORD_PTR)&mci_generic);
00408 
00409     if (mwi->lasterror)
00410         return mwi->lasterror;
00411 
00412     MCIWND_notify_mode(mwi);
00413     MCIWND_UpdateState(mwi);
00414     return 0;
00415 }
00416 
00417 static LRESULT mci_get_devcaps(MCIWndInfo *mwi, UINT cap)
00418 {
00419     MCI_GETDEVCAPS_PARMS mci_devcaps;
00420 
00421     mci_devcaps.dwItem = cap;
00422     mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
00423                                    MCI_GETDEVCAPS_ITEM,
00424                                    (DWORD_PTR)&mci_devcaps);
00425     if (mwi->lasterror)
00426         return 0;
00427 
00428     return mci_devcaps.dwReturn;
00429 }
00430 
00431 static LRESULT MCIWND_KeyDown(MCIWndInfo *mwi, UINT key)
00432 {
00433     TRACE("%p, key %04x\n", mwi->hWnd, key);
00434 
00435     switch(key)
00436     {
00437     case VK_ESCAPE:
00438         SendMessageW(mwi->hWnd, MCI_STOP, 0, 0);
00439         return 0;
00440 
00441     default:
00442         return 0;
00443     }
00444 }
00445 
00446 static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
00447 {
00448     MCIWndInfo *mwi;
00449 
00450     TRACE("%p %04x %08lx %08lx\n", hWnd, wMsg, wParam, lParam);
00451 
00452     mwi = (MCIWndInfo*)GetWindowLongPtrW(hWnd, 0);
00453     if (!mwi && wMsg != WM_CREATE)
00454         return DefWindowProcW(hWnd, wMsg, wParam, lParam);
00455 
00456     switch (wMsg)
00457     {
00458     case WM_CREATE:
00459         MCIWND_Create(hWnd, (CREATESTRUCTW *)lParam);
00460         break;
00461 
00462     case WM_DESTROY:
00463         if (mwi->uTimer)
00464             KillTimer(hWnd, mwi->uTimer);
00465 
00466         if (mwi->mci)
00467             SendMessageW(hWnd, MCI_CLOSE, 0, 0);
00468 
00469         HeapFree(GetProcessHeap(), 0, mwi);
00470 
00471         DestroyWindow(GetDlgItem(hWnd, CTL_MENU));
00472         DestroyWindow(GetDlgItem(hWnd, CTL_PLAYSTOP));
00473         DestroyWindow(GetDlgItem(hWnd, CTL_TRACKBAR));
00474         break;
00475 
00476     case WM_PAINT:
00477         {
00478             MCI_DGV_UPDATE_PARMS mci_update;
00479             PAINTSTRUCT ps;
00480 
00481             mci_update.hDC = (wParam) ? (HDC)wParam : BeginPaint(hWnd, &ps);
00482 
00483             mciSendCommandW(mwi->mci, MCI_UPDATE,
00484                             MCI_DGV_UPDATE_HDC | MCI_DGV_UPDATE_PAINT,
00485                             (DWORD_PTR)&mci_update);
00486 
00487             if (!wParam) EndPaint(hWnd, &ps);
00488             return 1;
00489         }
00490 
00491     case WM_COMMAND:
00492         return MCIWND_Command(mwi, wParam, lParam);
00493 
00494     case WM_KEYDOWN:
00495         return MCIWND_KeyDown(mwi, wParam);
00496 
00497     case WM_NCACTIVATE:
00498         if (mwi->uTimer)
00499         {
00500             KillTimer(hWnd, mwi->uTimer);
00501             mwi->uTimer = SetTimer(hWnd, 1, wParam ? mwi->active_timer : mwi->inactive_timer, NULL);
00502         }
00503         break;
00504 
00505     case WM_TIMER:
00506         MCIWND_UpdateState(mwi);
00507         return 0;
00508 
00509     case WM_SIZE:
00510         SetWindowPos(GetDlgItem(hWnd, CTL_PLAYSTOP), 0, 0, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
00511         SetWindowPos(GetDlgItem(hWnd, CTL_MENU), 0, 32, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
00512         SetWindowPos(GetDlgItem(hWnd, CTL_TRACKBAR), 0, 64, HIWORD(lParam) - 32, LOWORD(lParam) - 64, 32, SWP_NOACTIVATE);
00513 
00514         if (!(mwi->dwStyle & MCIWNDF_NOAUTOSIZEMOVIE))
00515         {
00516             RECT rc;
00517 
00518             rc.left = rc.top = 0;
00519             rc.right = LOWORD(lParam);
00520             rc.bottom = HIWORD(lParam);
00521             if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
00522                 rc.bottom -= 32; /* subtract the height of the playbar */
00523             SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc);
00524         }
00525         MCIWND_notify_size(mwi);
00526         break;
00527 
00528     case MM_MCINOTIFY:
00529         MCIWND_notify_mode(mwi);
00530         MCIWND_UpdateState(mwi);
00531         return 0;
00532 
00533     case MCIWNDM_OPENA:
00534         {
00535             UNICODE_STRING nameW;
00536             TRACE("MCIWNDM_OPENA %s\n", debugstr_a((LPSTR)lParam));
00537             RtlCreateUnicodeStringFromAsciiz(&nameW, (LPCSTR)lParam);
00538             lParam = (LPARAM)nameW.Buffer;
00539         }
00540         /* fall through */
00541     case MCIWNDM_OPENW:
00542         {
00543             RECT rc;
00544             HCURSOR hCursor;
00545             MCI_OPEN_PARMSW mci_open;
00546             MCI_GETDEVCAPS_PARMS mci_devcaps;
00547             WCHAR aliasW[64];
00548             WCHAR drv_name[MAX_PATH];
00549             static const WCHAR formatW[] = {'%','d',0};
00550             static const WCHAR mci32W[] = {'m','c','i','3','2',0};
00551             static const WCHAR system_iniW[] = {'s','y','s','t','e','m','.','i','n','i',0};
00552 
00553             TRACE("MCIWNDM_OPENW %s\n", debugstr_w((LPWSTR)lParam));
00554 
00555             if (wParam == MCIWNDOPENF_NEW)
00556             {
00557                 SendMessageW(hWnd, MCIWNDM_NEWW, 0, lParam);
00558                 goto end_of_mci_open;
00559             }
00560 
00561             if (mwi->uTimer)
00562             {
00563                 KillTimer(hWnd, mwi->uTimer);
00564                 mwi->uTimer = 0;
00565             }
00566 
00567             hCursor = LoadCursorW(0, (LPWSTR)IDC_WAIT);
00568             hCursor = SetCursor(hCursor);
00569 
00570             mci_open.lpstrElementName = (LPWSTR)lParam;
00571             wsprintfW(aliasW, formatW, HandleToLong(hWnd) + 1);
00572             mci_open.lpstrAlias = aliasW;
00573             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_OPEN,
00574                                              MCI_OPEN_ELEMENT | MCI_OPEN_ALIAS | MCI_WAIT,
00575                                              (DWORD_PTR)&mci_open);
00576             SetCursor(hCursor);
00577 
00578             if (mwi->lasterror && !(mwi->dwStyle & MCIWNDF_NOERRORDLG))
00579             {
00580                 /* FIXME: get the caption from resources */
00581                 static const WCHAR caption[] = {'M','C','I',' ','E','r','r','o','r',0};
00582                 WCHAR error_str[MAXERRORLENGTH];
00583 
00584                 mciGetErrorStringW(mwi->lasterror, error_str, MAXERRORLENGTH);
00585                 MessageBoxW(hWnd, error_str, caption, MB_ICONEXCLAMATION | MB_OK);
00586                 MCIWND_notify_error(mwi);
00587                 goto end_of_mci_open;
00588             }
00589 
00590             mwi->mci = mci_open.wDeviceID;
00591             mwi->alias = HandleToLong(hWnd) + 1;
00592 
00593             mwi->lpName = HeapAlloc(GetProcessHeap(), 0, (strlenW((LPWSTR)lParam) + 1) * sizeof(WCHAR));
00594             strcpyW(mwi->lpName, (LPWSTR)lParam);
00595 
00596             MCIWND_UpdateState(mwi);
00597 
00598             mci_devcaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
00599             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
00600                                              MCI_GETDEVCAPS_ITEM,
00601                                              (DWORD_PTR)&mci_devcaps);
00602             if (mwi->lasterror)
00603             {
00604                 MCIWND_notify_error(mwi);
00605                 goto end_of_mci_open;
00606             }
00607 
00608             mwi->dev_type = mci_devcaps.dwReturn;
00609 
00610             drv_name[0] = 0;
00611             SendMessageW(hWnd, MCIWNDM_GETDEVICEW, 256, (LPARAM)drv_name);
00612             if (drv_name[0] && GetPrivateProfileStringW(mci32W, drv_name, NULL,
00613                                             drv_name, MAX_PATH, system_iniW))
00614                 mwi->hdrv = OpenDriver(drv_name, NULL, 0);
00615 
00616             if (mwi->dev_type == MCI_DEVTYPE_DIGITAL_VIDEO)
00617             {
00618                 MCI_DGV_WINDOW_PARMSW mci_window;
00619 
00620                 mci_window.hWnd = hWnd;
00621                 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WINDOW,
00622                                                  MCI_DGV_WINDOW_HWND,
00623                                                  (DWORD_PTR)&mci_window);
00624                 if (mwi->lasterror)
00625                 {
00626                     MCIWND_notify_error(mwi);
00627                     goto end_of_mci_open;
00628                 }
00629             }
00630 
00631             if (SendMessageW(hWnd, MCIWNDM_GET_DEST, 0, (LPARAM)&rc) == 0)
00632             {
00633                 mwi->size.cx = rc.right - rc.left;
00634                 mwi->size.cy = rc.bottom - rc.top;
00635 
00636                 rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100);
00637                 rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100);
00638                 SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc);
00639             }
00640             else
00641             {
00642                 GetClientRect(hWnd, &rc);
00643                 rc.bottom = rc.top;
00644             }
00645 
00646             if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
00647                 rc.bottom += 32; /* add the height of the playbar */
00648             AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
00649             SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
00650                          rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
00651 
00652             SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L);
00653             SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1,
00654                                 SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0));
00655             mwi->uTimer = SetTimer(hWnd, 1, mwi->active_timer, NULL);
00656 
00657             MCIWND_notify_media(mwi);
00658 
00659 end_of_mci_open:
00660             if (wMsg == MCIWNDM_OPENA)
00661                 HeapFree(GetProcessHeap(), 0, (void *)lParam);
00662             return mwi->lasterror;
00663         }
00664 
00665     case MCIWNDM_GETDEVICEID:
00666         TRACE("MCIWNDM_GETDEVICEID\n");
00667         return mwi->mci;
00668 
00669     case MCIWNDM_GETALIAS:
00670         TRACE("MCIWNDM_GETALIAS\n");
00671         return mwi->alias;
00672 
00673     case MCIWNDM_GET_SOURCE:
00674         {
00675             MCI_DGV_RECT_PARMS mci_rect;
00676 
00677             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE,
00678                                              MCI_DGV_WHERE_SOURCE,
00679                                              (DWORD_PTR)&mci_rect);
00680             if (mwi->lasterror)
00681             {
00682                 MCIWND_notify_error(mwi);
00683                 return mwi->lasterror;
00684             }
00685             *(RECT *)lParam = mci_rect.rc;
00686             TRACE("MCIWNDM_GET_SOURCE: %s\n", wine_dbgstr_rect(&mci_rect.rc));
00687             return 0;
00688         }
00689 
00690     case MCIWNDM_GET_DEST:
00691         {
00692             MCI_DGV_RECT_PARMS mci_rect;
00693 
00694             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE,
00695                                              MCI_DGV_WHERE_DESTINATION,
00696                                              (DWORD_PTR)&mci_rect);
00697             if (mwi->lasterror)
00698             {
00699                 MCIWND_notify_error(mwi);
00700                 return mwi->lasterror;
00701             }
00702             *(RECT *)lParam = mci_rect.rc;
00703             TRACE("MCIWNDM_GET_DEST: %s\n", wine_dbgstr_rect(&mci_rect.rc));
00704             return 0;
00705         }
00706 
00707     case MCIWNDM_PUT_SOURCE:
00708         {
00709             MCI_DGV_PUT_PARMS mci_put;
00710 
00711             mci_put.rc = *(RECT *)lParam;
00712             TRACE("MCIWNDM_PUT_SOURCE: %s\n", wine_dbgstr_rect(&mci_put.rc));
00713             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
00714                                              MCI_DGV_PUT_SOURCE,
00715                                              (DWORD_PTR)&mci_put);
00716             if (mwi->lasterror)
00717             {
00718                 MCIWND_notify_error(mwi);
00719                 return mwi->lasterror;
00720             }
00721             return 0;
00722         }
00723 
00724     case MCIWNDM_PUT_DEST:
00725         {
00726             MCI_DGV_PUT_PARMS mci_put;
00727 
00728             mci_put.rc = *(RECT *)lParam;
00729             TRACE("MCIWNDM_PUT_DEST: %s\n", wine_dbgstr_rect(&mci_put.rc));
00730 
00731             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
00732                                              MCI_DGV_PUT_DESTINATION | MCI_DGV_RECT,
00733                                              (DWORD_PTR)&mci_put);
00734             if (mwi->lasterror)
00735             {
00736                 MCIWND_notify_error(mwi);
00737                 return mwi->lasterror;
00738             }
00739             return 0;
00740         }
00741 
00742     case MCIWNDM_GETLENGTH:
00743         {
00744             MCI_STATUS_PARMS mci_status;
00745 
00746             mci_status.dwItem = MCI_STATUS_LENGTH;
00747             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
00748                                              MCI_STATUS_ITEM,
00749                                              (DWORD_PTR)&mci_status);
00750             if (mwi->lasterror)
00751             {
00752                 MCIWND_notify_error(mwi);
00753                 return 0;
00754             }
00755             TRACE("MCIWNDM_GETLENGTH: %ld\n", mci_status.dwReturn);
00756             return mci_status.dwReturn;
00757         }
00758 
00759     case MCIWNDM_GETSTART:
00760         {
00761             MCI_STATUS_PARMS mci_status;
00762 
00763             mci_status.dwItem = MCI_STATUS_POSITION;
00764             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
00765                                              MCI_STATUS_ITEM | MCI_STATUS_START,
00766                                              (DWORD_PTR)&mci_status);
00767             if (mwi->lasterror)
00768             {
00769                 MCIWND_notify_error(mwi);
00770                 return 0;
00771             }
00772             TRACE("MCIWNDM_GETSTART: %ld\n", mci_status.dwReturn);
00773             return mci_status.dwReturn;
00774         }
00775 
00776     case MCIWNDM_GETEND:
00777         {
00778             LRESULT start, length;
00779 
00780             start = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
00781             length = SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
00782             TRACE("MCIWNDM_GETEND: %ld\n", start + length);
00783             return (start + length);
00784         }
00785 
00786     case MCIWNDM_GETPOSITIONA:
00787     case MCIWNDM_GETPOSITIONW:
00788         {
00789             MCI_STATUS_PARMS mci_status;
00790 
00791             TRACE("MCIWNDM_GETPOSITION\n");
00792 
00793             /* get position string if requested */
00794             if (wParam && lParam)
00795             {
00796                 if (wMsg == MCIWNDM_GETPOSITIONA)
00797                 {
00798                     char cmd[64];
00799 
00800                     wsprintfA(cmd, "status %d position", mwi->alias);
00801                     mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
00802                 }
00803                 else
00804                 {
00805 
00806                     WCHAR cmdW[64];
00807                     static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','p','o','s','i','t','i','o','n',0};
00808 
00809                     wsprintfW(cmdW, formatW, mwi->alias);
00810                     mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
00811                 }
00812 
00813                 if (mwi->lasterror)
00814                     return 0;
00815             }
00816 
00817             mci_status.dwItem = MCI_STATUS_POSITION;
00818             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
00819                                              MCI_STATUS_ITEM,
00820                                              (DWORD_PTR)&mci_status);
00821             if (mwi->lasterror)
00822                 return 0;
00823 
00824             return mci_status.dwReturn;
00825         }
00826 
00827     case MCIWNDM_GETMODEA:
00828     case MCIWNDM_GETMODEW:
00829         {
00830             MCI_STATUS_PARMS mci_status;
00831 
00832             TRACE("MCIWNDM_GETMODE\n");
00833 
00834             if (!mwi->mci)
00835                 return MCI_MODE_NOT_READY;
00836 
00837             /* get mode string if requested */
00838             if (wParam && lParam)
00839             {
00840                 if (wMsg == MCIWNDM_GETMODEA)
00841                 {
00842                     char cmd[64];
00843 
00844                     wsprintfA(cmd, "status %d mode", mwi->alias);
00845                     mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
00846                 }
00847                 else
00848                 {
00849 
00850                     WCHAR cmdW[64];
00851                     static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','m','o','d','e',0};
00852 
00853                     wsprintfW(cmdW, formatW, mwi->alias);
00854                     mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
00855                 }
00856 
00857                 if (mwi->lasterror)
00858                     return MCI_MODE_NOT_READY;
00859             }
00860 
00861             mci_status.dwItem = MCI_STATUS_MODE;
00862             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
00863                                              MCI_STATUS_ITEM,
00864                                              (DWORD_PTR)&mci_status);
00865             if (mwi->lasterror)
00866                 return MCI_MODE_NOT_READY;
00867 
00868             return mci_status.dwReturn;
00869         }
00870 
00871     case MCIWNDM_PLAYFROM:
00872         {
00873             MCI_PLAY_PARMS mci_play;
00874 
00875             TRACE("MCIWNDM_PLAYFROM %08lx\n", lParam);
00876 
00877             mci_play.dwCallback = (DWORD_PTR)hWnd;
00878             mci_play.dwFrom = lParam;
00879             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
00880                                              MCI_FROM | MCI_NOTIFY,
00881                                              (DWORD_PTR)&mci_play);
00882             if (mwi->lasterror)
00883             {
00884                 MCIWND_notify_error(mwi);
00885                 return mwi->lasterror;
00886             }
00887 
00888             MCIWND_notify_mode(mwi);
00889             MCIWND_UpdateState(mwi);
00890             return 0;
00891         }
00892 
00893     case MCIWNDM_PLAYTO:
00894         {
00895             MCI_PLAY_PARMS mci_play;
00896 
00897             TRACE("MCIWNDM_PLAYTO %08lx\n", lParam);
00898 
00899             mci_play.dwCallback = (DWORD_PTR)hWnd;
00900             mci_play.dwTo = lParam;
00901             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
00902                                              MCI_TO | MCI_NOTIFY,
00903                                              (DWORD_PTR)&mci_play);
00904             if (mwi->lasterror)
00905             {
00906                 MCIWND_notify_error(mwi);
00907                 return mwi->lasterror;
00908             }
00909 
00910             MCIWND_notify_mode(mwi);
00911             MCIWND_UpdateState(mwi);
00912             return 0;
00913         }
00914 
00915     case MCIWNDM_PLAYREVERSE:
00916         {
00917             MCI_PLAY_PARMS mci_play;
00918             DWORD flags = MCI_NOTIFY;
00919 
00920             TRACE("MCIWNDM_PLAYREVERSE %08lx\n", lParam);
00921 
00922             mci_play.dwCallback = (DWORD_PTR)hWnd;
00923             mci_play.dwFrom = lParam;
00924             switch (mwi->dev_type)
00925             {
00926             default:
00927             case MCI_DEVTYPE_ANIMATION:
00928                 flags |= MCI_ANIM_PLAY_REVERSE;
00929                 break;
00930 
00931             case MCI_DEVTYPE_DIGITAL_VIDEO:
00932                 flags |= MCI_DGV_PLAY_REVERSE;
00933                 break;
00934 
00935 #ifdef MCI_VCR_PLAY_REVERSE
00936             case MCI_DEVTYPE_VCR:
00937                 flags |= MCI_VCR_PLAY_REVERSE;
00938                 break;
00939 #endif
00940 
00941             case MCI_DEVTYPE_VIDEODISC:
00942                 flags |= MCI_VD_PLAY_REVERSE;
00943                 break;
00944 
00945             }
00946             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
00947                                              flags, (DWORD_PTR)&mci_play);
00948             if (mwi->lasterror)
00949             {
00950                 MCIWND_notify_error(mwi);
00951                 return mwi->lasterror;
00952             }
00953 
00954             MCIWND_notify_mode(mwi);
00955             MCIWND_UpdateState(mwi);
00956             return 0;
00957         }
00958 
00959     case MCIWNDM_GETERRORA:
00960         mciGetErrorStringA(mwi->lasterror, (LPSTR)lParam, wParam);
00961         TRACE("MCIWNDM_GETERRORA: %s\n", debugstr_an((LPSTR)lParam, wParam));
00962         return mwi->lasterror;
00963 
00964     case MCIWNDM_GETERRORW:
00965         mciGetErrorStringW(mwi->lasterror, (LPWSTR)lParam, wParam);
00966         TRACE("MCIWNDM_GETERRORW: %s\n", debugstr_wn((LPWSTR)lParam, wParam));
00967         return mwi->lasterror;
00968 
00969     case MCIWNDM_SETOWNER:
00970         TRACE("MCIWNDM_SETOWNER %p\n", (HWND)wParam);
00971         mwi->hwndOwner = (HWND)wParam;
00972         return 0;
00973 
00974     case MCIWNDM_SENDSTRINGA:
00975         {
00976             UNICODE_STRING stringW;
00977 
00978             TRACE("MCIWNDM_SENDSTRINGA %s\n", debugstr_a((LPCSTR)lParam));
00979 
00980             RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
00981             lParam = (LPARAM)stringW.Buffer;
00982         }
00983         /* fall through */
00984     case MCIWNDM_SENDSTRINGW:
00985         {
00986             WCHAR *cmdW, *p;
00987 
00988             TRACE("MCIWNDM_SENDSTRINGW %s\n", debugstr_w((LPCWSTR)lParam));
00989 
00990             p = strchrW((LPCWSTR)lParam, ' ');
00991             if (p)
00992             {
00993                 static const WCHAR formatW[] = {'%','d',' ',0};
00994                 int len, pos;
00995 
00996                 pos = p - (WCHAR *)lParam + 1;
00997                 len = lstrlenW((LPCWSTR)lParam) + 64;
00998 
00999                 cmdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
01000 
01001                 memcpy(cmdW, (void *)lParam, pos * sizeof(WCHAR));
01002                 wsprintfW(cmdW + pos, formatW, mwi->alias);
01003                 strcatW(cmdW, (WCHAR *)lParam + pos);
01004             }
01005             else
01006                 cmdW = (LPWSTR)lParam;
01007 
01008             mwi->lasterror = mciSendStringW(cmdW, mwi->return_string,
01009                                             sizeof(mwi->return_string)/sizeof(mwi->return_string[0]),
01010                                             0);
01011             if (mwi->lasterror)
01012                 MCIWND_notify_error(mwi);
01013 
01014             if (cmdW != (LPWSTR)lParam)
01015                 HeapFree(GetProcessHeap(), 0, cmdW);
01016 
01017             if (wMsg == MCIWNDM_SENDSTRINGA)
01018                 HeapFree(GetProcessHeap(), 0, (void *)lParam);
01019 
01020             MCIWND_UpdateState(mwi);
01021             return mwi->lasterror;
01022         }
01023 
01024     case MCIWNDM_RETURNSTRINGA:
01025         WideCharToMultiByte(CP_ACP, 0, mwi->return_string, -1, (LPSTR)lParam, wParam, NULL, NULL);
01026         TRACE("MCIWNDM_RETURNTRINGA %s\n", debugstr_an((LPSTR)lParam, wParam));
01027         return mwi->lasterror;
01028 
01029     case MCIWNDM_RETURNSTRINGW:
01030         lstrcpynW((LPWSTR)lParam, mwi->return_string, wParam);
01031         TRACE("MCIWNDM_RETURNTRINGW %s\n", debugstr_wn((LPWSTR)lParam, wParam));
01032         return mwi->lasterror;
01033 
01034     case MCIWNDM_SETTIMERS:
01035         TRACE("MCIWNDM_SETTIMERS active %d ms, inactive %d ms\n", (int)wParam, (int)lParam);
01036         mwi->active_timer = (WORD)wParam;
01037         mwi->inactive_timer = (WORD)lParam;
01038         return 0;
01039 
01040     case MCIWNDM_SETACTIVETIMER:
01041         TRACE("MCIWNDM_SETACTIVETIMER %d ms\n", (int)wParam);
01042         mwi->active_timer = (WORD)wParam;
01043         return 0;
01044 
01045     case MCIWNDM_SETINACTIVETIMER:
01046         TRACE("MCIWNDM_SETINACTIVETIMER %d ms\n", (int)wParam);
01047         mwi->inactive_timer = (WORD)wParam;
01048         return 0;
01049 
01050     case MCIWNDM_GETACTIVETIMER:
01051         TRACE("MCIWNDM_GETACTIVETIMER: %d ms\n", mwi->active_timer);
01052         return mwi->active_timer;
01053 
01054     case MCIWNDM_GETINACTIVETIMER:
01055         TRACE("MCIWNDM_GETINACTIVETIMER: %d ms\n", mwi->inactive_timer);
01056         return mwi->inactive_timer;
01057 
01058     case MCIWNDM_CHANGESTYLES:
01059         TRACE("MCIWNDM_CHANGESTYLES mask %08lx, set %08lx\n", wParam, lParam);
01060         /* FIXME: update the visual window state as well:
01061          * add/remove trackbar, autosize, etc.
01062          */
01063         mwi->dwStyle &= ~wParam;
01064         mwi->dwStyle |= lParam & wParam;
01065         return 0;
01066 
01067     case MCIWNDM_GETSTYLES:
01068         TRACE("MCIWNDM_GETSTYLES: %08x\n", mwi->dwStyle & 0xffff);
01069         return mwi->dwStyle & 0xffff;
01070 
01071     case MCIWNDM_GETDEVICEA:
01072         {
01073             MCI_SYSINFO_PARMSA mci_sysinfo;
01074 
01075             mci_sysinfo.lpstrReturn = (LPSTR)lParam;
01076             mci_sysinfo.dwRetSize = wParam;
01077             mwi->lasterror = mciSendCommandA(mwi->mci, MCI_SYSINFO,
01078                                              MCI_SYSINFO_INSTALLNAME,
01079                                              (DWORD_PTR)&mci_sysinfo);
01080             TRACE("MCIWNDM_GETDEVICEA: %s\n", debugstr_an((LPSTR)lParam, wParam));
01081             return 0;
01082         }
01083 
01084     case MCIWNDM_GETDEVICEW:
01085         {
01086             MCI_SYSINFO_PARMSW mci_sysinfo;
01087 
01088             mci_sysinfo.lpstrReturn = (LPWSTR)lParam;
01089             mci_sysinfo.dwRetSize = wParam;
01090             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SYSINFO,
01091                                              MCI_SYSINFO_INSTALLNAME,
01092                                              (DWORD_PTR)&mci_sysinfo);
01093             TRACE("MCIWNDM_GETDEVICEW: %s\n", debugstr_wn((LPWSTR)lParam, wParam));
01094             return 0;
01095         }
01096 
01097     case MCIWNDM_VALIDATEMEDIA:
01098         TRACE("MCIWNDM_VALIDATEMEDIA\n");
01099         if (mwi->mci)
01100         {
01101             SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
01102             SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
01103         }
01104         return 0;
01105 
01106     case MCIWNDM_GETFILENAMEA:
01107         TRACE("MCIWNDM_GETFILENAMEA: %s\n", debugstr_w(mwi->lpName));
01108         if (mwi->lpName)
01109             WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, (LPSTR)lParam, wParam, NULL, NULL);
01110         return 0;
01111 
01112     case MCIWNDM_GETFILENAMEW:
01113         TRACE("MCIWNDM_GETFILENAMEW: %s\n", debugstr_w(mwi->lpName));
01114         if (mwi->lpName)
01115             lstrcpynW((LPWSTR)lParam, mwi->lpName, wParam);
01116         return 0;
01117 
01118     case MCIWNDM_GETTIMEFORMATA:
01119     case MCIWNDM_GETTIMEFORMATW:
01120         {
01121             MCI_STATUS_PARMS mci_status;
01122 
01123             TRACE("MCIWNDM_GETTIMEFORMAT %08lx %08lx\n", wParam, lParam);
01124 
01125             /* get format string if requested */
01126             if (wParam && lParam)
01127             {
01128                 if (wMsg == MCIWNDM_GETTIMEFORMATA)
01129                 {
01130                     char cmd[64];
01131 
01132                     wsprintfA(cmd, "status %d time format", mwi->alias);
01133                     mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
01134                     if (mwi->lasterror)
01135                         return 0;
01136                 }
01137                 else
01138                 {
01139                     WCHAR cmdW[64];
01140                     static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',0};
01141 
01142                     wsprintfW(cmdW, formatW, mwi->alias);
01143                     mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
01144                     if (mwi->lasterror)
01145                         return 0;
01146                 }
01147             }
01148 
01149             mci_status.dwItem = MCI_STATUS_TIME_FORMAT ;
01150             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
01151                                              MCI_STATUS_ITEM,
01152                                              (DWORD_PTR)&mci_status);
01153             if (mwi->lasterror)
01154                 return 0;
01155 
01156             return mci_status.dwReturn;
01157         }
01158 
01159     case MCIWNDM_SETTIMEFORMATA:
01160         {
01161             UNICODE_STRING stringW;
01162 
01163             TRACE("MCIWNDM_SETTIMEFORMATA %s\n", debugstr_a((LPSTR)lParam));
01164 
01165             RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
01166             lParam = (LPARAM)stringW.Buffer;
01167         }
01168         /* fall through */
01169     case MCIWNDM_SETTIMEFORMATW:
01170         {
01171             static const WCHAR formatW[] = {'s','e','t',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',' ',0};
01172             WCHAR *cmdW;
01173 
01174             TRACE("MCIWNDM_SETTIMEFORMATW %s\n", debugstr_w((LPWSTR)lParam));
01175 
01176             if (mwi->mci)
01177             {
01178                 cmdW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW((LPCWSTR)lParam) + 64) * sizeof(WCHAR));
01179                 wsprintfW(cmdW, formatW, mwi->alias);
01180                 strcatW(cmdW, (WCHAR *)lParam);
01181 
01182                 mwi->lasterror = mciSendStringW(cmdW, NULL, 0, 0);
01183 
01184                 /* fix the range tracking according to the new time format */
01185                 if (!mwi->lasterror)
01186                     SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1,
01187                                         SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0));
01188 
01189                 HeapFree(GetProcessHeap(), 0, cmdW);
01190             }
01191 
01192             if (wMsg == MCIWNDM_SETTIMEFORMATA)
01193                 HeapFree(GetProcessHeap(), 0, (void *)lParam);
01194 
01195             return 0;
01196         }
01197 
01198     case MCIWNDM_CAN_PLAY:
01199         TRACE("MCIWNDM_CAN_PLAY\n");
01200         if (mwi->mci)
01201             return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_PLAY);
01202         return 0;
01203 
01204     case MCIWNDM_CAN_RECORD:
01205         TRACE("MCIWNDM_CAN_RECORD\n");
01206         if (mwi->mci)
01207             return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_RECORD);
01208         return 0;
01209 
01210     case MCIWNDM_CAN_SAVE:
01211         TRACE("MCIWNDM_CAN_SAVE\n");
01212         if (mwi->mci)
01213             return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_SAVE);
01214         return 0;
01215 
01216     case MCIWNDM_CAN_EJECT:
01217         TRACE("MCIWNDM_CAN_EJECT\n");
01218         if (mwi->mci)
01219             return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_EJECT);
01220         return 0;
01221 
01222     case MCIWNDM_CAN_WINDOW:
01223         TRACE("MCIWNDM_CAN_WINDOW\n");
01224         switch (mwi->dev_type)
01225         {
01226         case MCI_DEVTYPE_ANIMATION:
01227         case MCI_DEVTYPE_DIGITAL_VIDEO:
01228         case MCI_DEVTYPE_OVERLAY:
01229             return 1;
01230         }
01231         return 0;
01232 
01233     case MCIWNDM_CAN_CONFIG:
01234         TRACE("MCIWNDM_CAN_CONFIG\n");
01235         if (mwi->hdrv)
01236             return SendDriverMessage(mwi->hdrv, DRV_QUERYCONFIGURE, 0, 0);
01237         return 0;
01238 
01239     case MCIWNDM_SETZOOM:
01240         TRACE("MCIWNDM_SETZOOM %ld\n", lParam);
01241         mwi->zoom = lParam;
01242 
01243         if (mwi->mci && !(mwi->dwStyle & MCIWNDF_NOAUTOSIZEWINDOW))
01244         {
01245             RECT rc;
01246 
01247             rc.left = rc.top = 0;
01248             rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100);
01249             rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100);
01250 
01251             if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
01252                 rc.bottom += 32; /* add the height of the playbar */
01253             AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
01254             SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
01255                          SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
01256         }
01257         return 0;
01258 
01259     case MCIWNDM_GETZOOM:
01260         TRACE("MCIWNDM_GETZOOM: %d\n", mwi->zoom);
01261         return mwi->zoom;
01262 
01263     case MCIWNDM_EJECT:
01264         {
01265             MCI_SET_PARMS mci_set;
01266 
01267             TRACE("MCIWNDM_EJECT\n");
01268 
01269             mci_set.dwCallback = (DWORD_PTR)hWnd;
01270             mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SET,
01271                                              MCI_SET_DOOR_OPEN | MCI_NOTIFY,
01272                                              (DWORD_PTR)&mci_set);
01273             MCIWND_notify_mode(mwi);
01274             MCIWND_UpdateState(mwi);
01275             return mwi->lasterror;
01276         }
01277 
01278     case MCIWNDM_SETVOLUME:
01279     case MCIWNDM_GETVOLUME:
01280     case MCIWNDM_SETSPEED:
01281     case MCIWNDM_GETSPEED:
01282     case MCIWNDM_SETREPEAT:
01283     case MCIWNDM_GETREPEAT:
01284     case MCIWNDM_REALIZE:
01285     case MCIWNDM_GETPALETTE:
01286     case MCIWNDM_SETPALETTE:
01287     case MCIWNDM_NEWA:
01288     case MCIWNDM_NEWW:
01289     case MCIWNDM_PALETTEKICK:
01290     case MCIWNDM_OPENINTERFACE:
01291         FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER);
01292         return 0;
01293 
01294     case MCI_PLAY:
01295         {
01296             LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
01297             return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end);
01298         }
01299 
01300     case MCI_SEEK:
01301     case MCI_STEP:
01302         {
01303             MCI_SEEK_PARMS mci_seek; /* Layout is usable as MCI_XYZ_STEP_PARMS */
01304             DWORD flags = MCI_STEP == wMsg ? 0 :
01305                           MCIWND_START == lParam ? MCI_SEEK_TO_START :
01306                           MCIWND_END   == lParam ? MCI_SEEK_TO_END : MCI_TO;
01307 
01308             mci_seek.dwTo = lParam;
01309             mwi->lasterror = mciSendCommandW(mwi->mci, wMsg,
01310                                              flags, (DWORD_PTR)&mci_seek);
01311             if (mwi->lasterror)
01312             {
01313                 MCIWND_notify_error(mwi);
01314                 return mwi->lasterror;
01315             }
01316             /* update window to reflect the state */
01317             else InvalidateRect(hWnd, NULL, TRUE);
01318             return 0;
01319         }
01320 
01321     case MCI_CLOSE:
01322         {
01323             RECT rc;
01324             MCI_GENERIC_PARMS mci_generic;
01325 
01326             if (mwi->hdrv)
01327             {
01328                 CloseDriver(mwi->hdrv, 0, 0);
01329                 mwi->hdrv = 0;
01330             }
01331 
01332             if (mwi->mci)
01333             {
01334                 mci_generic.dwCallback = 0;
01335                 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE,
01336                                                  0, (DWORD_PTR)&mci_generic);
01337                 mwi->mci = 0;
01338             }
01339 
01340             mwi->mode = MCI_MODE_NOT_READY;
01341             mwi->position = -1;
01342 
01343             HeapFree(GetProcessHeap(), 0, mwi->lpName);
01344             mwi->lpName = NULL;
01345             MCIWND_UpdateState(mwi);
01346 
01347             GetClientRect(hWnd, &rc);
01348             rc.bottom = rc.top;
01349             if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
01350                 rc.bottom += 32; /* add the height of the playbar */
01351             AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
01352             SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
01353                          rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
01354 
01355             MCIWND_notify_media(mwi);
01356             return 0;
01357         }
01358 
01359     case MCI_PAUSE:
01360     case MCI_STOP:
01361     case MCI_RESUME:
01362         mci_generic_command(mwi, wMsg);
01363         return mwi->lasterror;
01364 
01365     case MCI_CONFIGURE:
01366         if (mwi->hdrv)
01367             SendDriverMessage(mwi->hdrv, DRV_CONFIGURE, (LPARAM)hWnd, 0);
01368         return 0;
01369 
01370     case MCI_BREAK:
01371     case MCI_CAPTURE:
01372     case MCI_COPY:
01373     case MCI_CUE:
01374     case MCI_CUT:
01375     case MCI_DELETE:
01376     case MCI_ESCAPE:
01377     case MCI_FREEZE:
01378     case MCI_GETDEVCAPS:
01379     /*case MCI_INDEX:*/
01380     case MCI_INFO:
01381     case MCI_LIST:
01382     case MCI_LOAD:
01383     /*case MCI_MARK:*/
01384     case MCI_MONITOR:
01385     case MCI_OPEN:
01386     case MCI_PASTE:
01387     case MCI_PUT:
01388     case MCI_QUALITY:
01389     case MCI_REALIZE:
01390     case MCI_RECORD:
01391     case MCI_RESERVE:
01392     case MCI_RESTORE:
01393     case MCI_SAVE:
01394     case MCI_SET:
01395     case MCI_SETAUDIO:
01396     /*case MCI_SETTIMECODE:*/
01397     /*case MCI_SETTUNER:*/
01398     case MCI_SETVIDEO:
01399     case MCI_SIGNAL:
01400     case MCI_SPIN:
01401     case MCI_STATUS:
01402     case MCI_SYSINFO:
01403     case MCI_UNDO:
01404     case MCI_UNFREEZE:
01405     case MCI_UPDATE:
01406     case MCI_WHERE:
01407     case MCI_WINDOW:
01408         FIXME("support for MCI_ command %04x not implemented\n", wMsg);
01409         return 0;
01410     }
01411 
01412     if (wMsg >= WM_USER)
01413     {
01414         FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER);
01415         return 0;
01416     }
01417 
01418     if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
01419         return DefMDIChildProcW(hWnd, wMsg, wParam, lParam);
01420 
01421     return DefWindowProcW(hWnd, wMsg, wParam, lParam);
01422 }

Generated on Sun May 27 2012 04:25:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.