Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmciwnd.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
1.7.6.1
|