| /* |
| * Copyright 2000 Eric Pouech |
| * Copyright 2003 Dmitry Timoshkov |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| * |
| * FIXME: |
| * Add support for all remaining MCI_ commands and MCIWNDM_ messages. |
| * Add support for MCIWNDF_RECORD. |
| */ |
| |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winnls.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winreg.h" |
| #include "winternl.h" |
| #include "vfw.h" |
| #include "digitalv.h" |
| #include "commctrl.h" |
| #include "wine/unicode.h" |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(mci); |
| |
| extern HMODULE MSVFW32_hModule; |
| static const WCHAR mciWndClassW[] = {'M','C','I','W','n','d','C','l','a','s','s',0}; |
| |
| typedef struct |
| { |
| DWORD dwStyle; |
| MCIDEVICEID mci; |
| HDRVR hdrv; |
| int alias; |
| UINT dev_type; |
| UINT mode; |
| long position; |
| SIZE size; /* size of the original frame rect */ |
| int zoom; |
| LPWSTR lpName; |
| HWND hWnd, hwndOwner; |
| UINT uTimer; |
| MCIERROR lasterror; |
| WCHAR return_string[128]; |
| WORD active_timer, inactive_timer; |
| } MCIWndInfo; |
| |
| static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); |
| |
| #define CTL_PLAYSTOP 0x3200 |
| #define CTL_MENU 0x3201 |
| #define CTL_TRACKBAR 0x3202 |
| |
| /*********************************************************************** |
| * MCIWndRegisterClass [MSVFW32.@] |
| * |
| * NOTE: Native always uses its own hInstance |
| */ |
| BOOL VFWAPIV MCIWndRegisterClass(void) |
| { |
| WNDCLASSW wc; |
| |
| /* Since we are going to register a class belonging to MSVFW32 |
| * and later we will create windows with a different hInstance |
| * CS_GLOBALCLASS is needed. And because the second attempt |
| * to register a global class will fail we need to test whether |
| * the class was already registered. |
| */ |
| wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC | CS_GLOBALCLASS; |
| wc.lpfnWndProc = MCIWndProc; |
| wc.cbClsExtra = 0; |
| wc.cbWndExtra = sizeof(MCIWndInfo*); |
| wc.hInstance = MSVFW32_hModule; |
| wc.hIcon = 0; |
| wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDC_ARROW)); |
| wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); |
| wc.lpszMenuName = NULL; |
| wc.lpszClassName = mciWndClassW; |
| |
| if (RegisterClassW(&wc)) return TRUE; |
| if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE; |
| |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * MCIWndCreateW [MSVFW32.@] |
| */ |
| HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, |
| DWORD dwStyle, LPCWSTR szFile) |
| { |
| TRACE("%p %p %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile)); |
| |
| MCIWndRegisterClass(); |
| |
| if (!hInstance) hInstance = GetModuleHandleW(0); |
| |
| if (hwndParent) |
| dwStyle |= WS_VISIBLE | WS_BORDER /*| WS_CHILD*/; |
| else |
| dwStyle |= WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; |
| |
| return CreateWindowExW(0, mciWndClassW, NULL, |
| dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, |
| 0, 0, 300, 0, |
| hwndParent, 0, hInstance, (LPVOID)szFile); |
| } |
| |
| /*********************************************************************** |
| * MCIWndCreate [MSVFW32.@] |
| * MCIWndCreateA [MSVFW32.@] |
| */ |
| HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance, |
| DWORD dwStyle, LPCSTR szFile) |
| { |
| HWND ret; |
| UNICODE_STRING fileW; |
| |
| if (szFile) |
| RtlCreateUnicodeStringFromAsciiz(&fileW, szFile); |
| else |
| fileW.Buffer = NULL; |
| |
| ret = MCIWndCreateW(hwndParent, hInstance, dwStyle, fileW.Buffer); |
| |
| RtlFreeUnicodeString(&fileW); |
| return ret; |
| } |
| |
| static inline void MCIWND_notify_mode(MCIWndInfo *mwi) |
| { |
| if (mwi->dwStyle & MCIWNDF_NOTIFYMODE) |
| { |
| UINT new_mode = SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0); |
| if (new_mode != mwi->mode) |
| { |
| mwi->mode = new_mode; |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)mwi->hWnd, new_mode); |
| } |
| } |
| } |
| |
| static inline void MCIWND_notify_pos(MCIWndInfo *mwi) |
| { |
| if (mwi->dwStyle & MCIWNDF_NOTIFYPOS) |
| { |
| long new_pos = SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 0, 0); |
| if (new_pos != mwi->position) |
| { |
| mwi->position = new_pos; |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYPOS, (WPARAM)mwi->hWnd, new_pos); |
| } |
| } |
| } |
| |
| static inline void MCIWND_notify_size(MCIWndInfo *mwi) |
| { |
| if (mwi->dwStyle & MCIWNDF_NOTIFYSIZE) |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYSIZE, (WPARAM)mwi->hWnd, 0); |
| } |
| |
| static inline void MCIWND_notify_error(MCIWndInfo *mwi) |
| { |
| if (mwi->dwStyle & MCIWNDF_NOTIFYERROR) |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYERROR, (WPARAM)mwi->hWnd, (LPARAM)mwi->lasterror); |
| } |
| |
| static void MCIWND_UpdateState(MCIWndInfo *mwi) |
| { |
| WCHAR buffer[1024]; |
| |
| if (!mwi->mci) |
| { |
| /* FIXME: get this from resources */ |
| static const WCHAR no_deviceW[] = {'N','o',' ','D','e','v','i','c','e',0}; |
| SetWindowTextW(mwi->hWnd, no_deviceW); |
| return; |
| } |
| |
| MCIWND_notify_pos(mwi); |
| |
| if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR)) |
| SendDlgItemMessageW(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, TRUE, mwi->position); |
| |
| if (!(mwi->dwStyle & MCIWNDF_SHOWALL)) |
| return; |
| |
| if ((mwi->dwStyle & MCIWNDF_SHOWNAME) && mwi->lpName) |
| strcpyW(buffer, mwi->lpName); |
| else |
| *buffer = 0; |
| |
| if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) |
| { |
| static const WCHAR spaceW[] = {' ',0}; |
| static const WCHAR l_braceW[] = {'(',0}; |
| |
| if (*buffer) strcatW(buffer, spaceW); |
| strcatW(buffer, l_braceW); |
| } |
| |
| if (mwi->dwStyle & MCIWNDF_SHOWPOS) |
| { |
| WCHAR posW[64]; |
| |
| posW[0] = 0; |
| SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 64, (LPARAM)posW); |
| strcatW(buffer, posW); |
| } |
| |
| if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) |
| { |
| static const WCHAR dashW[] = {' ','-',' ',0}; |
| strcatW(buffer, dashW); |
| } |
| |
| if (mwi->dwStyle & MCIWNDF_SHOWMODE) |
| { |
| WCHAR modeW[64]; |
| |
| modeW[0] = 0; |
| SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 64, (LPARAM)modeW); |
| strcatW(buffer, modeW); |
| } |
| |
| if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) |
| { |
| static const WCHAR r_braceW[] = {')',0}; |
| strcatW(buffer, r_braceW); |
| } |
| |
| TRACE("=> '%s'\n", debugstr_w(buffer)); |
| SetWindowTextW(mwi->hWnd, buffer); |
| } |
| |
| static LRESULT MCIWND_Create(HWND hWnd, LPCREATESTRUCTW cs) |
| { |
| HWND hChld; |
| MCIWndInfo *mwi; |
| static const WCHAR buttonW[] = {'b','u','t','t','o','n',0}; |
| |
| mwi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*mwi)); |
| if (!mwi) return -1; |
| |
| SetWindowLongW(hWnd, 0, (LPARAM)mwi); |
| |
| mwi->dwStyle = cs->style; |
| /* There is no need to show stats if there is no caption */ |
| if ((mwi->dwStyle & WS_CAPTION) != WS_CAPTION) |
| mwi->dwStyle &= ~MCIWNDF_SHOWALL; |
| |
| mwi->hWnd = hWnd; |
| mwi->hwndOwner = cs->hwndParent; |
| mwi->active_timer = 500; |
| mwi->inactive_timer = 2000; |
| mwi->mode = MCI_MODE_NOT_READY; |
| mwi->position = -1; |
| mwi->zoom = 100; |
| |
| if (!(mwi->dwStyle & MCIWNDF_NOMENU)) |
| { |
| static const WCHAR menuW[] = {'M','e','n','u',0}; |
| |
| hChld = CreateWindowExW(0, buttonW, menuW, WS_CHILD|WS_VISIBLE, 32, cs->cy, 32, 32, |
| hWnd, (HMENU)CTL_MENU, cs->hInstance, 0L); |
| TRACE("Get Button2: %p\n", hChld); |
| } |
| |
| if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR)) |
| { |
| INITCOMMONCONTROLSEX init; |
| static const WCHAR playW[] = {'P','l','a','y',0}; |
| |
| /* adding the other elements: play/stop button, menu button, status */ |
| hChld = CreateWindowExW(0, buttonW, playW, WS_CHILD|WS_VISIBLE, 0, cs->cy, 32, 32, |
| hWnd, (HMENU)CTL_PLAYSTOP, cs->hInstance, 0L); |
| TRACE("Get Button1: %p\n", hChld); |
| |
| init.dwSize = sizeof(init); |
| init.dwICC = ICC_BAR_CLASSES; |
| InitCommonControlsEx(&init); |
| |
| hChld = CreateWindowExW(0, TRACKBAR_CLASSW, NULL, WS_CHILD|WS_VISIBLE, 64, cs->cy, cs->cx - 64, 32, |
| hWnd, (HMENU)CTL_TRACKBAR, cs->hInstance, 0L); |
| TRACE("Get status: %p\n", hChld); |
| } |
| |
| /* This sets the default window size */ |
| SendMessageW(hWnd, MCI_CLOSE, 0, 0); |
| |
| if (cs->lpCreateParams) |
| { |
| LPARAM lParam; |
| |
| /* MCI wnd class is prepared to be embedded as an MDI child window */ |
| if (cs->dwExStyle & WS_EX_MDICHILD) |
| { |
| MDICREATESTRUCTW *mdics = (MDICREATESTRUCTW *)cs->lpCreateParams; |
| lParam = mdics->lParam; |
| } |
| else |
| lParam = (LPARAM)cs->lpCreateParams; |
| |
| /* If it's our internal class pointer, file name is a unicode string */ |
| if (cs->lpszClass == mciWndClassW) |
| SendMessageW(hWnd, MCIWNDM_OPENW, 0, lParam); |
| else |
| { |
| /* Otherwise let's try to figure out what string format is used */ |
| HWND parent = cs->hwndParent; |
| if (!parent) parent = GetWindow(hWnd, GW_OWNER); |
| |
| SendMessageW(hWnd, IsWindowUnicode(parent) ? MCIWNDM_OPENW : MCIWNDM_OPENA, 0, lParam); |
| } |
| } |
| |
| return 0; |
| } |
| |
| static void MCIWND_ToggleState(MCIWndInfo *mwi) |
| { |
| switch (SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0)) |
| { |
| case MCI_MODE_NOT_READY: |
| case MCI_MODE_RECORD: |
| case MCI_MODE_SEEK: |
| case MCI_MODE_OPEN: |
| TRACE("Cannot do much...\n"); |
| break; |
| |
| case MCI_MODE_PAUSE: |
| SendMessageW(mwi->hWnd, MCI_RESUME, 0, 0); |
| break; |
| |
| case MCI_MODE_PLAY: |
| SendMessageW(mwi->hWnd, MCI_PAUSE, 0, 0); |
| break; |
| |
| case MCI_MODE_STOP: |
| SendMessageW(mwi->hWnd, MCI_STOP, 0, 0); |
| break; |
| } |
| } |
| |
| static LRESULT MCIWND_Command(MCIWndInfo *mwi, WPARAM wParam, LPARAM lParam) |
| { |
| switch (LOWORD(wParam)) |
| { |
| case CTL_PLAYSTOP: MCIWND_ToggleState(mwi); break; |
| case CTL_MENU: |
| case CTL_TRACKBAR: |
| default: |
| FIXME("support for command %04x not implement yet\n", LOWORD(wParam)); |
| } |
| return 0L; |
| } |
| |
| static void MCIWND_notify_media(MCIWndInfo *mwi) |
| { |
| if (mwi->dwStyle & (MCIWNDF_NOTIFYMEDIAA | MCIWNDF_NOTIFYMEDIAW)) |
| { |
| if (!mwi->lpName) |
| { |
| static const WCHAR empty_str[1]; |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)empty_str); |
| } |
| else |
| { |
| if (mwi->dwStyle & MCIWNDF_NOTIFYANSI) |
| { |
| char *ansi_name; |
| int len; |
| |
| len = WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, NULL, 0, NULL, NULL); |
| ansi_name = HeapAlloc(GetProcessHeap(), 0, len); |
| WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, ansi_name, len, NULL, NULL); |
| |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)ansi_name); |
| |
| HeapFree(GetProcessHeap(), 0, ansi_name); |
| } |
| else |
| SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)mwi->lpName); |
| } |
| } |
| } |
| |
| static MCIERROR mci_generic_command(MCIWndInfo *mwi, UINT cmd) |
| { |
| MCI_GENERIC_PARMS mci_generic; |
| |
| mci_generic.dwCallback = 0; |
| mwi->lasterror = mciSendCommandW(mwi->mci, cmd, 0, (DWORD_PTR)&mci_generic); |
| |
| if (mwi->lasterror) |
| return mwi->lasterror; |
| |
| MCIWND_notify_mode(mwi); |
| MCIWND_UpdateState(mwi); |
| return 0; |
| } |
| |
| static LRESULT mci_get_devcaps(MCIWndInfo *mwi, UINT cap) |
| { |
| MCI_GETDEVCAPS_PARMS mci_devcaps; |
| |
| mci_devcaps.dwItem = cap; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS, |
| MCI_GETDEVCAPS_ITEM, |
| (DWORD_PTR)&mci_devcaps); |
| if (mwi->lasterror) |
| return 0; |
| |
| return mci_devcaps.dwReturn; |
| } |
| |
| static LRESULT MCIWND_KeyDown(MCIWndInfo *mwi, UINT key) |
| { |
| TRACE("%p, key %04x\n", mwi->hWnd, key); |
| |
| switch(key) |
| { |
| case VK_ESCAPE: |
| SendMessageW(mwi->hWnd, MCI_STOP, 0, 0); |
| return 0; |
| |
| default: |
| return 0; |
| } |
| } |
| |
| static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) |
| { |
| MCIWndInfo *mwi; |
| |
| TRACE("%p %04x %08x %08lx\n", hWnd, wMsg, wParam, lParam); |
| |
| mwi = (MCIWndInfo*)GetWindowLongW(hWnd, 0); |
| if (!mwi && wMsg != WM_CREATE) |
| return DefWindowProcW(hWnd, wMsg, wParam, lParam); |
| |
| switch (wMsg) |
| { |
| case WM_CREATE: |
| MCIWND_Create(hWnd, (CREATESTRUCTW *)lParam); |
| break; |
| |
| case WM_DESTROY: |
| if (mwi->uTimer) |
| KillTimer(hWnd, mwi->uTimer); |
| |
| if (mwi->mci) |
| SendMessageW(hWnd, MCI_CLOSE, 0, 0); |
| |
| HeapFree(GetProcessHeap(), 0, mwi); |
| |
| DestroyWindow(GetDlgItem(hWnd, CTL_MENU)); |
| DestroyWindow(GetDlgItem(hWnd, CTL_PLAYSTOP)); |
| DestroyWindow(GetDlgItem(hWnd, CTL_TRACKBAR)); |
| break; |
| |
| case WM_PAINT: |
| { |
| MCI_DGV_UPDATE_PARMS mci_update; |
| PAINTSTRUCT ps; |
| |
| mci_update.hDC = (wParam) ? (HDC)wParam : BeginPaint(hWnd, &ps); |
| |
| mciSendCommandW(mwi->mci, MCI_UPDATE, |
| MCI_DGV_UPDATE_HDC | MCI_DGV_UPDATE_PAINT, |
| (DWORD_PTR)&mci_update); |
| |
| if (!wParam) EndPaint(hWnd, &ps); |
| return 1; |
| } |
| |
| case WM_COMMAND: |
| return MCIWND_Command(mwi, wParam, lParam); |
| |
| case WM_KEYDOWN: |
| return MCIWND_KeyDown(mwi, wParam); |
| |
| case WM_NCACTIVATE: |
| if (mwi->uTimer) |
| { |
| KillTimer(hWnd, mwi->uTimer); |
| mwi->uTimer = SetTimer(hWnd, 1, wParam ? mwi->active_timer : mwi->inactive_timer, NULL); |
| } |
| break; |
| |
| case WM_TIMER: |
| MCIWND_UpdateState(mwi); |
| return 0; |
| |
| case WM_SIZE: |
| SetWindowPos(GetDlgItem(hWnd, CTL_PLAYSTOP), 0, 0, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE); |
| SetWindowPos(GetDlgItem(hWnd, CTL_MENU), 0, 32, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE); |
| SetWindowPos(GetDlgItem(hWnd, CTL_TRACKBAR), 0, 64, HIWORD(lParam) - 32, LOWORD(lParam) - 64, 32, SWP_NOACTIVATE); |
| |
| if (!(mwi->dwStyle & MCIWNDF_NOAUTOSIZEMOVIE)) |
| { |
| RECT rc; |
| |
| rc.left = rc.top = 0; |
| rc.right = LOWORD(lParam); |
| rc.bottom = HIWORD(lParam); |
| if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR)) |
| rc.bottom -= 32; /* subtract the height of the playbar */ |
| SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc); |
| } |
| MCIWND_notify_size(mwi); |
| break; |
| |
| case MM_MCINOTIFY: |
| MCIWND_notify_mode(mwi); |
| MCIWND_UpdateState(mwi); |
| return 0; |
| |
| case MCIWNDM_OPENA: |
| { |
| UNICODE_STRING nameW; |
| TRACE("MCIWNDM_OPENA %s\n", debugstr_a((LPSTR)lParam)); |
| RtlCreateUnicodeStringFromAsciiz(&nameW, (LPCSTR)lParam); |
| lParam = (LPARAM)nameW.Buffer; |
| } |
| /* fall through */ |
| case MCIWNDM_OPENW: |
| { |
| RECT rc; |
| HCURSOR hCursor; |
| MCI_OPEN_PARMSW mci_open; |
| MCI_GETDEVCAPS_PARMS mci_devcaps; |
| WCHAR aliasW[64]; |
| WCHAR drv_name[MAX_PATH]; |
| static const WCHAR formatW[] = {'%','d',0}; |
| static const WCHAR mci32W[] = {'m','c','i','3','2',0}; |
| static const WCHAR system_iniW[] = {'s','y','s','t','e','m','.','i','n','i',0}; |
| |
| TRACE("MCIWNDM_OPENW %s\n", debugstr_w((LPWSTR)lParam)); |
| |
| if (wParam == MCIWNDOPENF_NEW) |
| { |
| SendMessageW(hWnd, MCIWNDM_NEWW, 0, lParam); |
| goto end_of_mci_open; |
| } |
| |
| if (mwi->uTimer) |
| { |
| KillTimer(hWnd, mwi->uTimer); |
| mwi->uTimer = 0; |
| } |
| |
| hCursor = LoadCursorW(0, (LPWSTR)IDC_WAIT); |
| hCursor = SetCursor(hCursor); |
| |
| mci_open.lpstrElementName = (LPWSTR)lParam; |
| wsprintfW(aliasW, formatW, (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 && !(mwi->dwStyle & MCIWNDF_NOERRORDLG)) |
| { |
| /* FIXME: get the caption from resources */ |
| static const WCHAR caption[] = {'M','C','I',' ','E','r','r','o','r',0}; |
| WCHAR error_str[MAXERRORLENGTH]; |
| |
| mciGetErrorStringW(mwi->lasterror, error_str, MAXERRORLENGTH); |
| MessageBoxW(hWnd, error_str, caption, MB_ICONEXCLAMATION | MB_OK); |
| MCIWND_notify_error(mwi); |
| goto end_of_mci_open; |
| } |
| |
| mwi->mci = mci_open.wDeviceID; |
| mwi->alias = (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; |
| |
| mci_window.hWnd = hWnd; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WINDOW, |
| MCI_DGV_WINDOW_HWND, |
| (DWORD_PTR)&mci_window); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| goto end_of_mci_open; |
| } |
| } |
| |
| if (SendMessageW(hWnd, MCIWNDM_GET_DEST, 0, (LPARAM)&rc) == 0) |
| { |
| mwi->size.cx = rc.right - rc.left; |
| mwi->size.cy = rc.bottom - rc.top; |
| |
| rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100); |
| rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100); |
| SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc); |
| } |
| else |
| { |
| GetClientRect(hWnd, &rc); |
| rc.bottom = rc.top; |
| } |
| |
| if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR)) |
| rc.bottom += 32; /* add the height of the playbar */ |
| AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE); |
| SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left, |
| rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); |
| |
| SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L); |
| SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1, |
| SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0)); |
| mwi->uTimer = SetTimer(hWnd, 1, mwi->active_timer, NULL); |
| |
| MCIWND_notify_media(mwi); |
| |
| end_of_mci_open: |
| if (wMsg == MCIWNDM_OPENA) |
| HeapFree(GetProcessHeap(), 0, (void *)lParam); |
| return mwi->lasterror; |
| } |
| |
| case MCIWNDM_GETDEVICEID: |
| TRACE("MCIWNDM_GETDEVICEID\n"); |
| return mwi->mci; |
| |
| case MCIWNDM_GETALIAS: |
| TRACE("MCIWNDM_GETALIAS\n"); |
| return mwi->alias; |
| |
| case MCIWNDM_GET_SOURCE: |
| { |
| MCI_DGV_RECT_PARMS mci_rect; |
| |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE, |
| MCI_DGV_WHERE_SOURCE, |
| (DWORD_PTR)&mci_rect); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| *(RECT *)lParam = mci_rect.rc; |
| TRACE("MCIWNDM_GET_SOURCE: %s\n", wine_dbgstr_rect(&mci_rect.rc)); |
| return 0; |
| } |
| |
| case MCIWNDM_GET_DEST: |
| { |
| MCI_DGV_RECT_PARMS mci_rect; |
| |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE, |
| MCI_DGV_WHERE_DESTINATION, |
| (DWORD_PTR)&mci_rect); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| *(RECT *)lParam = mci_rect.rc; |
| TRACE("MCIWNDM_GET_DEST: %s\n", wine_dbgstr_rect(&mci_rect.rc)); |
| return 0; |
| } |
| |
| case MCIWNDM_PUT_SOURCE: |
| { |
| MCI_DGV_PUT_PARMS mci_put; |
| |
| mci_put.rc = *(RECT *)lParam; |
| TRACE("MCIWNDM_PUT_SOURCE: %s\n", wine_dbgstr_rect(&mci_put.rc)); |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT, |
| MCI_DGV_PUT_SOURCE, |
| (DWORD_PTR)&mci_put); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| return 0; |
| } |
| |
| case MCIWNDM_PUT_DEST: |
| { |
| MCI_DGV_PUT_PARMS mci_put; |
| |
| mci_put.rc = *(RECT *)lParam; |
| TRACE("MCIWNDM_PUT_DEST: %s\n", wine_dbgstr_rect(&mci_put.rc)); |
| |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT, |
| MCI_DGV_PUT_DESTINATION | MCI_DGV_RECT, |
| (DWORD_PTR)&mci_put); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| return 0; |
| } |
| |
| case MCIWNDM_GETLENGTH: |
| { |
| MCI_STATUS_PARMS mci_status; |
| |
| mci_status.dwItem = MCI_STATUS_LENGTH; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS, |
| MCI_STATUS_ITEM, |
| (DWORD_PTR)&mci_status); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return 0; |
| } |
| TRACE("MCIWNDM_GETLENGTH: %ld\n", mci_status.dwReturn); |
| return mci_status.dwReturn; |
| } |
| |
| case MCIWNDM_GETSTART: |
| { |
| MCI_STATUS_PARMS mci_status; |
| |
| mci_status.dwItem = MCI_STATUS_POSITION; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS, |
| MCI_STATUS_ITEM | MCI_STATUS_START, |
| (DWORD_PTR)&mci_status); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return 0; |
| } |
| TRACE("MCIWNDM_GETSTART: %ld\n", mci_status.dwReturn); |
| return mci_status.dwReturn; |
| } |
| |
| case MCIWNDM_GETEND: |
| { |
| LRESULT start, length; |
| |
| start = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0); |
| length = SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0); |
| TRACE("MCIWNDM_GETEND: %ld\n", start + length); |
| return (start + length); |
| } |
| |
| case MCIWNDM_GETPOSITIONA: |
| case MCIWNDM_GETPOSITIONW: |
| { |
| MCI_STATUS_PARMS mci_status; |
| |
| TRACE("MCIWNDM_GETPOSITION\n"); |
| |
| /* get position string if requested */ |
| if (wParam && lParam) |
| { |
| if (wMsg == MCIWNDM_GETPOSITIONA) |
| { |
| char cmd[64]; |
| |
| wsprintfA(cmd, "status %d position", mwi->alias); |
| mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0); |
| } |
| else |
| { |
| |
| WCHAR cmdW[64]; |
| static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','p','o','s','i','t','i','o','n',0}; |
| |
| wsprintfW(cmdW, formatW, mwi->alias); |
| mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0); |
| } |
| |
| if (mwi->lasterror) |
| return 0; |
| } |
| |
| mci_status.dwItem = MCI_STATUS_POSITION; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS, |
| MCI_STATUS_ITEM, |
| (DWORD_PTR)&mci_status); |
| if (mwi->lasterror) |
| return 0; |
| |
| return mci_status.dwReturn; |
| } |
| |
| case MCIWNDM_GETMODEA: |
| case MCIWNDM_GETMODEW: |
| { |
| MCI_STATUS_PARMS mci_status; |
| |
| TRACE("MCIWNDM_GETMODE\n"); |
| |
| if (!mwi->mci) |
| return MCI_MODE_NOT_READY; |
| |
| /* get mode string if requested */ |
| if (wParam && lParam) |
| { |
| if (wMsg == MCIWNDM_GETMODEA) |
| { |
| char cmd[64]; |
| |
| wsprintfA(cmd, "status %d mode", mwi->alias); |
| mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0); |
| } |
| else |
| { |
| |
| WCHAR cmdW[64]; |
| static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','m','o','d','e',0}; |
| |
| wsprintfW(cmdW, formatW, mwi->alias); |
| mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0); |
| } |
| |
| if (mwi->lasterror) |
| return MCI_MODE_NOT_READY; |
| } |
| |
| mci_status.dwItem = MCI_STATUS_MODE; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS, |
| MCI_STATUS_ITEM, |
| (DWORD_PTR)&mci_status); |
| if (mwi->lasterror) |
| return MCI_MODE_NOT_READY; |
| |
| return mci_status.dwReturn; |
| } |
| |
| case MCIWNDM_PLAYFROM: |
| { |
| MCI_PLAY_PARMS mci_play; |
| |
| TRACE("MCIWNDM_PLAYFROM %08lx\n", lParam); |
| |
| mci_play.dwCallback = (DWORD_PTR)hWnd; |
| mci_play.dwFrom = lParam; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY, |
| MCI_FROM | MCI_NOTIFY, |
| (DWORD_PTR)&mci_play); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| |
| MCIWND_notify_mode(mwi); |
| MCIWND_UpdateState(mwi); |
| return 0; |
| } |
| |
| case MCIWNDM_PLAYTO: |
| { |
| MCI_PLAY_PARMS mci_play; |
| |
| TRACE("MCIWNDM_PLAYTO %08lx\n", lParam); |
| |
| mci_play.dwCallback = (DWORD_PTR)hWnd; |
| mci_play.dwTo = lParam; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY, |
| MCI_TO | MCI_NOTIFY, |
| (DWORD_PTR)&mci_play); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| |
| MCIWND_notify_mode(mwi); |
| MCIWND_UpdateState(mwi); |
| return 0; |
| } |
| |
| case MCIWNDM_PLAYREVERSE: |
| { |
| MCI_PLAY_PARMS mci_play; |
| DWORD flags = MCI_NOTIFY; |
| |
| TRACE("MCIWNDM_PLAYREVERSE %08lx\n", lParam); |
| |
| mci_play.dwCallback = (DWORD_PTR)hWnd; |
| mci_play.dwFrom = lParam; |
| switch (mwi->dev_type) |
| { |
| default: |
| case MCI_DEVTYPE_ANIMATION: |
| flags |= MCI_ANIM_PLAY_REVERSE; |
| break; |
| |
| case MCI_DEVTYPE_DIGITAL_VIDEO: |
| flags |= MCI_DGV_PLAY_REVERSE; |
| break; |
| |
| #ifdef MCI_VCR_PLAY_REVERSE |
| case MCI_DEVTYPE_VCR: |
| flags |= MCI_VCR_PLAY_REVERSE; |
| break; |
| #endif |
| |
| case MCI_DEVTYPE_VIDEODISC: |
| flags |= MCI_VD_PLAY_REVERSE; |
| break; |
| |
| } |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY, |
| flags, (DWORD_PTR)&mci_play); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| |
| MCIWND_notify_mode(mwi); |
| MCIWND_UpdateState(mwi); |
| return 0; |
| } |
| |
| case MCIWNDM_GETERRORA: |
| mciGetErrorStringA(mwi->lasterror, (LPSTR)lParam, wParam); |
| TRACE("MCIWNDM_GETERRORA: %s\n", debugstr_an((LPSTR)lParam, wParam)); |
| return mwi->lasterror; |
| |
| case MCIWNDM_GETERRORW: |
| mciGetErrorStringW(mwi->lasterror, (LPWSTR)lParam, wParam); |
| TRACE("MCIWNDM_GETERRORW: %s\n", debugstr_wn((LPWSTR)lParam, wParam)); |
| return mwi->lasterror; |
| |
| case MCIWNDM_SETOWNER: |
| TRACE("MCIWNDM_SETOWNER %p\n", (HWND)wParam); |
| mwi->hwndOwner = (HWND)wParam; |
| return 0; |
| |
| case MCIWNDM_SENDSTRINGA: |
| { |
| UNICODE_STRING stringW; |
| |
| TRACE("MCIWNDM_SENDSTRINGA %s\n", debugstr_a((LPCSTR)lParam)); |
| |
| RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam); |
| lParam = (LPARAM)stringW.Buffer; |
| } |
| /* fall through */ |
| case MCIWNDM_SENDSTRINGW: |
| { |
| WCHAR *cmdW, *p; |
| |
| TRACE("MCIWNDM_SENDSTRINGW %s\n", debugstr_w((LPCWSTR)lParam)); |
| |
| p = strchrW((LPCWSTR)lParam, ' '); |
| if (p) |
| { |
| static const WCHAR formatW[] = {'%','d',' ',0}; |
| int len, pos; |
| |
| pos = p - (WCHAR *)lParam + 1; |
| len = lstrlenW((LPCWSTR)lParam) + 64; |
| |
| cmdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); |
| |
| memcpy(cmdW, (void *)lParam, pos * sizeof(WCHAR)); |
| wsprintfW(cmdW + pos, formatW, mwi->alias); |
| strcatW(cmdW, (WCHAR *)lParam + pos); |
| } |
| else |
| cmdW = (LPWSTR)lParam; |
| |
| mwi->lasterror = mciSendStringW(cmdW, mwi->return_string, |
| sizeof(mwi->return_string)/sizeof(mwi->return_string[0]), |
| 0); |
| if (mwi->lasterror) |
| MCIWND_notify_error(mwi); |
| |
| if (cmdW != (LPWSTR)lParam) |
| HeapFree(GetProcessHeap(), 0, cmdW); |
| |
| if (wMsg == MCIWNDM_SENDSTRINGA) |
| HeapFree(GetProcessHeap(), 0, (void *)lParam); |
| |
| MCIWND_UpdateState(mwi); |
| return mwi->lasterror; |
| } |
| |
| case MCIWNDM_RETURNSTRINGA: |
| WideCharToMultiByte(CP_ACP, 0, mwi->return_string, -1, (LPSTR)lParam, wParam, NULL, NULL); |
| TRACE("MCIWNDM_RETURNTRINGA %s\n", debugstr_an((LPSTR)lParam, wParam)); |
| return mwi->lasterror; |
| |
| case MCIWNDM_RETURNSTRINGW: |
| lstrcpynW((LPWSTR)lParam, mwi->return_string, wParam); |
| TRACE("MCIWNDM_RETURNTRINGW %s\n", debugstr_wn((LPWSTR)lParam, wParam)); |
| return mwi->lasterror; |
| |
| case MCIWNDM_SETTIMERS: |
| TRACE("MCIWNDM_SETTIMERS active %d ms, inactive %d ms\n", (int)wParam, (int)lParam); |
| mwi->active_timer = (WORD)wParam; |
| mwi->inactive_timer = (WORD)lParam; |
| return 0; |
| |
| case MCIWNDM_SETACTIVETIMER: |
| TRACE("MCIWNDM_SETACTIVETIMER %d ms\n", (int)wParam); |
| mwi->active_timer = (WORD)wParam; |
| return 0; |
| |
| case MCIWNDM_SETINACTIVETIMER: |
| TRACE("MCIWNDM_SETINACTIVETIMER %d ms\n", (int)wParam); |
| mwi->inactive_timer = (WORD)wParam; |
| return 0; |
| |
| case MCIWNDM_GETACTIVETIMER: |
| TRACE("MCIWNDM_GETACTIVETIMER: %d ms\n", mwi->active_timer); |
| return mwi->active_timer; |
| |
| case MCIWNDM_GETINACTIVETIMER: |
| TRACE("MCIWNDM_GETINACTIVETIMER: %d ms\n", mwi->inactive_timer); |
| return mwi->inactive_timer; |
| |
| case MCIWNDM_CHANGESTYLES: |
| TRACE("MCIWNDM_CHANGESTYLES mask %08x, set %08lx\n", wParam, lParam); |
| /* FIXME: update the visual window state as well: |
| * add/remove trackbar, autosize, etc. |
| */ |
| mwi->dwStyle &= ~wParam; |
| mwi->dwStyle |= lParam & wParam; |
| return 0; |
| |
| case MCIWNDM_GETSTYLES: |
| TRACE("MCIWNDM_GETSTYLES: %08lx\n", mwi->dwStyle & 0xffff); |
| return mwi->dwStyle & 0xffff; |
| |
| case MCIWNDM_GETDEVICEA: |
| { |
| MCI_SYSINFO_PARMSA mci_sysinfo; |
| |
| mci_sysinfo.lpstrReturn = (LPSTR)lParam; |
| mci_sysinfo.dwRetSize = wParam; |
| mwi->lasterror = mciSendCommandA(mwi->mci, MCI_SYSINFO, |
| MCI_SYSINFO_INSTALLNAME, |
| (DWORD_PTR)&mci_sysinfo); |
| TRACE("MCIWNDM_GETDEVICEA: %s\n", debugstr_an((LPSTR)lParam, wParam)); |
| return 0; |
| } |
| |
| case MCIWNDM_GETDEVICEW: |
| { |
| MCI_SYSINFO_PARMSW mci_sysinfo; |
| |
| mci_sysinfo.lpstrReturn = (LPWSTR)lParam; |
| mci_sysinfo.dwRetSize = wParam; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SYSINFO, |
| MCI_SYSINFO_INSTALLNAME, |
| (DWORD_PTR)&mci_sysinfo); |
| TRACE("MCIWNDM_GETDEVICEW: %s\n", debugstr_wn((LPWSTR)lParam, wParam)); |
| return 0; |
| } |
| |
| case MCIWNDM_VALIDATEMEDIA: |
| TRACE("MCIWNDM_VALIDATEMEDIA\n"); |
| if (mwi->mci) |
| { |
| SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0); |
| SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0); |
| } |
| return 0; |
| |
| case MCIWNDM_GETFILENAMEA: |
| TRACE("MCIWNDM_GETFILENAMEA: %s\n", debugstr_w(mwi->lpName)); |
| if (mwi->lpName) |
| WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, (LPSTR)lParam, wParam, NULL, NULL); |
| return 0; |
| |
| case MCIWNDM_GETFILENAMEW: |
| TRACE("MCIWNDM_GETFILENAMEW: %s\n", debugstr_w(mwi->lpName)); |
| if (mwi->lpName) |
| lstrcpynW((LPWSTR)lParam, mwi->lpName, wParam); |
| return 0; |
| |
| case MCIWNDM_GETTIMEFORMATA: |
| case MCIWNDM_GETTIMEFORMATW: |
| { |
| MCI_STATUS_PARMS mci_status; |
| |
| TRACE("MCIWNDM_GETTIMEFORMAT %08x %08lx\n", wParam, lParam); |
| |
| /* get format string if requested */ |
| if (wParam && lParam) |
| { |
| if (wMsg == MCIWNDM_GETTIMEFORMATA) |
| { |
| char cmd[64]; |
| |
| wsprintfA(cmd, "status %d time format", mwi->alias); |
| mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0); |
| if (mwi->lasterror) |
| return 0; |
| } |
| else |
| { |
| WCHAR cmdW[64]; |
| static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',0}; |
| |
| wsprintfW(cmdW, formatW, mwi->alias); |
| mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0); |
| if (mwi->lasterror) |
| return 0; |
| } |
| } |
| |
| mci_status.dwItem = MCI_STATUS_TIME_FORMAT ; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS, |
| MCI_STATUS_ITEM, |
| (DWORD_PTR)&mci_status); |
| if (mwi->lasterror) |
| return 0; |
| |
| return mci_status.dwReturn; |
| } |
| |
| case MCIWNDM_SETTIMEFORMATA: |
| { |
| UNICODE_STRING stringW; |
| |
| TRACE("MCIWNDM_SETTIMEFORMATA %s\n", debugstr_a((LPSTR)lParam)); |
| |
| RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam); |
| lParam = (LPARAM)stringW.Buffer; |
| } |
| /* fall through */ |
| case MCIWNDM_SETTIMEFORMATW: |
| { |
| static const WCHAR formatW[] = {'s','e','t',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',' ',0}; |
| WCHAR *cmdW; |
| |
| TRACE("MCIWNDM_SETTIMEFORMATW %s\n", debugstr_w((LPWSTR)lParam)); |
| |
| if (mwi->mci) |
| { |
| cmdW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW((LPCWSTR)lParam) + 64) * sizeof(WCHAR)); |
| wsprintfW(cmdW, formatW, mwi->alias); |
| strcatW(cmdW, (WCHAR *)lParam); |
| |
| mwi->lasterror = mciSendStringW(cmdW, NULL, 0, 0); |
| |
| /* fix the range tracking according to the new time format */ |
| if (!mwi->lasterror) |
| SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1, |
| SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0)); |
| } |
| |
| if (wMsg == MCIWNDM_SETTIMEFORMATA) |
| HeapFree(GetProcessHeap(), 0, (void *)lParam); |
| |
| return 0; |
| } |
| |
| case MCIWNDM_CAN_PLAY: |
| TRACE("MCIWNDM_CAN_PLAY\n"); |
| if (mwi->mci) |
| return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_PLAY); |
| return 0; |
| |
| case MCIWNDM_CAN_RECORD: |
| TRACE("MCIWNDM_CAN_RECORD\n"); |
| if (mwi->mci) |
| return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_RECORD); |
| return 0; |
| |
| case MCIWNDM_CAN_SAVE: |
| TRACE("MCIWNDM_CAN_SAVE\n"); |
| if (mwi->mci) |
| return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_SAVE); |
| return 0; |
| |
| case MCIWNDM_CAN_EJECT: |
| TRACE("MCIWNDM_CAN_EJECT\n"); |
| if (mwi->mci) |
| return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_EJECT); |
| return 0; |
| |
| case MCIWNDM_CAN_WINDOW: |
| TRACE("MCIWNDM_CAN_WINDOW\n"); |
| switch (mwi->dev_type) |
| { |
| case MCI_DEVTYPE_ANIMATION: |
| case MCI_DEVTYPE_DIGITAL_VIDEO: |
| case MCI_DEVTYPE_OVERLAY: |
| return 1; |
| } |
| return 0; |
| |
| case MCIWNDM_CAN_CONFIG: |
| TRACE("MCIWNDM_CAN_CONFIG\n"); |
| if (mwi->hdrv) |
| return SendDriverMessage(mwi->hdrv, DRV_QUERYCONFIGURE, 0, 0); |
| return 0; |
| |
| case MCIWNDM_SETZOOM: |
| TRACE("MCIWNDM_SETZOOM %ld\n", lParam); |
| mwi->zoom = lParam; |
| |
| if (mwi->mci && !(mwi->dwStyle & MCIWNDF_NOAUTOSIZEWINDOW)) |
| { |
| RECT rc; |
| |
| rc.left = rc.top = 0; |
| rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100); |
| rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100); |
| |
| if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR)) |
| rc.bottom += 32; /* add the height of the playbar */ |
| AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE); |
| SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, |
| SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); |
| } |
| return 0; |
| |
| case MCIWNDM_GETZOOM: |
| TRACE("MCIWNDM_GETZOOM: %d\n", mwi->zoom); |
| return mwi->zoom; |
| |
| case MCIWNDM_EJECT: |
| { |
| MCI_SET_PARMS mci_set; |
| |
| TRACE("MCIWNDM_EJECT\n"); |
| |
| mci_set.dwCallback = (DWORD_PTR)hWnd; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SET, |
| MCI_SET_DOOR_OPEN | MCI_NOTIFY, |
| (DWORD_PTR)&mci_set); |
| MCIWND_notify_mode(mwi); |
| MCIWND_UpdateState(mwi); |
| return mwi->lasterror; |
| } |
| |
| case MCIWNDM_SETVOLUME: |
| case MCIWNDM_GETVOLUME: |
| case MCIWNDM_SETSPEED: |
| case MCIWNDM_GETSPEED: |
| case MCIWNDM_SETREPEAT: |
| case MCIWNDM_GETREPEAT: |
| case MCIWNDM_REALIZE: |
| case MCIWNDM_GETPALETTE: |
| case MCIWNDM_SETPALETTE: |
| case MCIWNDM_NEWA: |
| case MCIWNDM_NEWW: |
| case MCIWNDM_PALETTEKICK: |
| case MCIWNDM_OPENINTERFACE: |
| FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER); |
| return 0; |
| |
| case MCI_PLAY: |
| { |
| LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0); |
| return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end); |
| } |
| |
| case MCI_SEEK: |
| { |
| MCI_SEEK_PARMS mci_seek; |
| |
| switch (lParam) |
| { |
| case MCIWND_START: |
| lParam = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0); |
| break; |
| |
| case MCIWND_END: |
| lParam = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0); |
| break; |
| } |
| |
| mci_seek.dwTo = lParam; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SEEK, |
| MCI_TO, (DWORD_PTR)&mci_seek); |
| if (mwi->lasterror) |
| { |
| MCIWND_notify_error(mwi); |
| return mwi->lasterror; |
| } |
| /* update window to reflect the state */ |
| InvalidateRect(hWnd, NULL, TRUE); |
| return 0; |
| } |
| |
| case MCI_CLOSE: |
| { |
| RECT rc; |
| MCI_GENERIC_PARMS mci_generic; |
| |
| if (mwi->hdrv) |
| { |
| CloseDriver(mwi->hdrv, 0, 0); |
| mwi->hdrv = 0; |
| } |
| |
| if (mwi->mci) |
| { |
| mci_generic.dwCallback = 0; |
| mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE, |
| 0, (DWORD_PTR)&mci_generic); |
| mwi->mci = 0; |
| } |
| |
| mwi->mode = MCI_MODE_NOT_READY; |
| mwi->position = -1; |
| |
| HeapFree(GetProcessHeap(), 0, mwi->lpName); |
| mwi->lpName = NULL; |
| MCIWND_UpdateState(mwi); |
| |
| GetClientRect(hWnd, &rc); |
| rc.bottom = rc.top; |
| if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR)) |
| rc.bottom += 32; /* add the height of the playbar */ |
| AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE); |
| SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left, |
| rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); |
| |
| MCIWND_notify_media(mwi); |
| return 0; |
| } |
| |
| case MCI_PAUSE: |
| case MCI_STEP: |
| case MCI_STOP: |
| case MCI_RESUME: |
| mci_generic_command(mwi, wMsg); |
| if (wMsg == MCI_STEP && !mwi->lasterror) |
| { |
| /* update window to reflect the state */ |
| InvalidateRect(hWnd, NULL, TRUE); |
| } |
| return mwi->lasterror; |
| |
| case MCI_CONFIGURE: |
| if (mwi->hdrv) |
| SendDriverMessage(mwi->hdrv, DRV_CONFIGURE, (LPARAM)hWnd, 0); |
| return 0; |
| |
| case MCI_BREAK: |
| case MCI_CAPTURE: |
| case MCI_COPY: |
| case MCI_CUE: |
| case MCI_CUT: |
| case MCI_DELETE: |
| case MCI_ESCAPE: |
| case MCI_FREEZE: |
| case MCI_GETDEVCAPS: |
| /*case MCI_INDEX:*/ |
| case MCI_INFO: |
| case MCI_LIST: |
| case MCI_LOAD: |
| /*case MCI_MARK:*/ |
| case MCI_MONITOR: |
| case MCI_OPEN: |
| case MCI_PASTE: |
| case MCI_PUT: |
| case MCI_QUALITY: |
| case MCI_REALIZE: |
| case MCI_RECORD: |
| case MCI_RESERVE: |
| case MCI_RESTORE: |
| case MCI_SAVE: |
| case MCI_SET: |
| case MCI_SETAUDIO: |
| /*case MCI_SETTIMECODE:*/ |
| /*case MCI_SETTUNER:*/ |
| case MCI_SETVIDEO: |
| case MCI_SIGNAL: |
| case MCI_SPIN: |
| case MCI_STATUS: |
| case MCI_SYSINFO: |
| case MCI_UNDO: |
| case MCI_UNFREEZE: |
| case MCI_UPDATE: |
| case MCI_WHERE: |
| case MCI_WINDOW: |
| FIXME("support for MCI_ command %04x not implemented\n", wMsg); |
| return 0; |
| } |
| |
| if (wMsg >= WM_USER) |
| { |
| FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER); |
| return 0; |
| } |
| |
| if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_MDICHILD) |
| return DefMDIChildProcW(hWnd, wMsg, wParam, lParam); |
| |
| return DefWindowProcW(hWnd, wMsg, wParam, lParam); |
| } |