blob: 46a5877a38a46ae6571ecf48ffae006eafec1fe1 [file] [log] [blame]
Eric Pouecha3d3d402001-08-18 18:02:34 +00001/*
Vincent BĂ©ron9a624912002-05-31 23:06:46 +00002 * Copyright 2000 Eric Pouech
Dmitry Timoshkov06464992003-12-15 20:17:11 +00003 * Copyright 2003 Dmitry Timoshkov
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00004 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
Jonathan Ernst360a3f92006-05-18 14:49:52 +020017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Dmitry Timoshkov06464992003-12-15 20:17:11 +000018 *
19 * FIXME:
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +000020 * Add support for all remaining MCI_ commands and MCIWNDM_ messages.
Dmitry Timoshkov19924762004-03-01 23:38:25 +000021 * Add support for MCIWNDF_RECORD.
Eric Pouecha3d3d402001-08-18 18:02:34 +000022 */
23
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000024#include <stdarg.h>
Eric Pouecha3d3d402001-08-18 18:02:34 +000025
Eric Pouecha3d3d402001-08-18 18:02:34 +000026#include "windef.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000027#include "winbase.h"
Eric Pouecha3d3d402001-08-18 18:02:34 +000028#include "winnls.h"
29#include "wingdi.h"
30#include "winuser.h"
Dmitry Timoshkov06464992003-12-15 20:17:11 +000031#include "winreg.h"
32#include "winternl.h"
Eric Pouecha3d3d402001-08-18 18:02:34 +000033#include "vfw.h"
Eric Pouecha3d3d402001-08-18 18:02:34 +000034#include "digitalv.h"
35#include "commctrl.h"
Dmitry Timoshkov06464992003-12-15 20:17:11 +000036#include "wine/unicode.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000037#include "wine/debug.h"
Eric Pouecha3d3d402001-08-18 18:02:34 +000038
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000039WINE_DEFAULT_DEBUG_CHANNEL(mci);
Eric Pouecha3d3d402001-08-18 18:02:34 +000040
Dmitry Timoshkov06464992003-12-15 20:17:11 +000041extern HMODULE MSVFW32_hModule;
42static const WCHAR mciWndClassW[] = {'M','C','I','W','n','d','C','l','a','s','s',0};
43
44typedef struct
45{
46 DWORD dwStyle;
47 MCIDEVICEID mci;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +000048 HDRVR hdrv;
49 int alias;
Dmitry Timoshkov06464992003-12-15 20:17:11 +000050 UINT dev_type;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +000051 UINT mode;
52 long position;
53 SIZE size; /* size of the original frame rect */
54 int zoom;
Dmitry Timoshkov06464992003-12-15 20:17:11 +000055 LPWSTR lpName;
56 HWND hWnd, hwndOwner;
57 UINT uTimer;
58 MCIERROR lasterror;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +000059 WCHAR return_string[128];
60 WORD active_timer, inactive_timer;
Eric Pouecha3d3d402001-08-18 18:02:34 +000061} MCIWndInfo;
62
Dmitry Timoshkov06464992003-12-15 20:17:11 +000063static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
64
65#define CTL_PLAYSTOP 0x3200
66#define CTL_MENU 0x3201
67#define CTL_TRACKBAR 0x3202
Eric Pouecha3d3d402001-08-18 18:02:34 +000068
69/***********************************************************************
Dmitry Timoshkov06464992003-12-15 20:17:11 +000070 * MCIWndRegisterClass [MSVFW32.@]
71 *
72 * NOTE: Native always uses its own hInstance
Eric Pouecha3d3d402001-08-18 18:02:34 +000073 */
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +000074BOOL VFWAPIV MCIWndRegisterClass(void)
Eric Pouecha3d3d402001-08-18 18:02:34 +000075{
Dmitry Timoshkov06464992003-12-15 20:17:11 +000076 WNDCLASSW wc;
Eric Pouecha3d3d402001-08-18 18:02:34 +000077
Dmitry Timoshkovbe6d0142003-12-31 19:00:03 +000078 /* Since we are going to register a class belonging to MSVFW32
79 * and later we will create windows with a different hInstance
80 * CS_GLOBALCLASS is needed. And because the second attempt
81 * to register a global class will fail we need to test whether
82 * the class was already registered.
83 */
84 wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC | CS_GLOBALCLASS;
Dmitry Timoshkov06464992003-12-15 20:17:11 +000085 wc.lpfnWndProc = MCIWndProc;
86 wc.cbClsExtra = 0;
87 wc.cbWndExtra = sizeof(MCIWndInfo*);
88 wc.hInstance = MSVFW32_hModule;
89 wc.hIcon = 0;
90 wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDC_ARROW));
91 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
92 wc.lpszMenuName = NULL;
93 wc.lpszClassName = mciWndClassW;
Eric Pouecha3d3d402001-08-18 18:02:34 +000094
Dmitry Timoshkovbe6d0142003-12-31 19:00:03 +000095 if (RegisterClassW(&wc)) return TRUE;
96 if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE;
97
98 return FALSE;
Eric Pouecha3d3d402001-08-18 18:02:34 +000099}
100
101/***********************************************************************
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000102 * MCIWndCreateW [MSVFW32.@]
Eric Pouecha3d3d402001-08-18 18:02:34 +0000103 */
104HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000105 DWORD dwStyle, LPCWSTR szFile)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000106{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000107 TRACE("%p %p %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));
Eric Pouecha3d3d402001-08-18 18:02:34 +0000108
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000109 MCIWndRegisterClass();
Eric Pouecha3d3d402001-08-18 18:02:34 +0000110
Dmitry Timoshkov2ae461e2004-02-27 04:32:16 +0000111 if (!hInstance) hInstance = GetModuleHandleW(0);
112
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000113 if (hwndParent)
114 dwStyle |= WS_VISIBLE | WS_BORDER /*| WS_CHILD*/;
115 else
116 dwStyle |= WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000117
118 return CreateWindowExW(0, mciWndClassW, NULL,
119 dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
120 0, 0, 300, 0,
121 hwndParent, 0, hInstance, (LPVOID)szFile);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000122}
123
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000124/***********************************************************************
125 * MCIWndCreate [MSVFW32.@]
126 * MCIWndCreateA [MSVFW32.@]
127 */
128HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
129 DWORD dwStyle, LPCSTR szFile)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000130{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000131 HWND ret;
132 UNICODE_STRING fileW;
Vincent BĂ©ron9a624912002-05-31 23:06:46 +0000133
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000134 if (szFile)
135 RtlCreateUnicodeStringFromAsciiz(&fileW, szFile);
136 else
137 fileW.Buffer = NULL;
138
139 ret = MCIWndCreateW(hwndParent, hInstance, dwStyle, fileW.Buffer);
140
141 RtlFreeUnicodeString(&fileW);
142 return ret;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000143}
144
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000145static inline void MCIWND_notify_mode(MCIWndInfo *mwi)
146{
147 if (mwi->dwStyle & MCIWNDF_NOTIFYMODE)
148 {
149 UINT new_mode = SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0);
150 if (new_mode != mwi->mode)
151 {
152 mwi->mode = new_mode;
153 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)mwi->hWnd, new_mode);
154 }
155 }
156}
157
158static inline void MCIWND_notify_pos(MCIWndInfo *mwi)
159{
160 if (mwi->dwStyle & MCIWNDF_NOTIFYPOS)
161 {
162 long new_pos = SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 0, 0);
163 if (new_pos != mwi->position)
164 {
165 mwi->position = new_pos;
166 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYPOS, (WPARAM)mwi->hWnd, new_pos);
167 }
168 }
169}
170
171static inline void MCIWND_notify_size(MCIWndInfo *mwi)
172{
173 if (mwi->dwStyle & MCIWNDF_NOTIFYSIZE)
174 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYSIZE, (WPARAM)mwi->hWnd, 0);
175}
176
177static inline void MCIWND_notify_error(MCIWndInfo *mwi)
178{
179 if (mwi->dwStyle & MCIWNDF_NOTIFYERROR)
180 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYERROR, (WPARAM)mwi->hWnd, (LPARAM)mwi->lasterror);
181}
182
183static void MCIWND_UpdateState(MCIWndInfo *mwi)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000184{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000185 WCHAR buffer[1024];
Vincent BĂ©ron9a624912002-05-31 23:06:46 +0000186
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000187 if (!mwi->mci)
188 {
189 /* FIXME: get this from resources */
190 static const WCHAR no_deviceW[] = {'N','o',' ','D','e','v','i','c','e',0};
191 SetWindowTextW(mwi->hWnd, no_deviceW);
192 return;
193 }
194
195 MCIWND_notify_pos(mwi);
196
197 if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
198 SendDlgItemMessageW(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, TRUE, mwi->position);
199
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000200 if (!(mwi->dwStyle & MCIWNDF_SHOWALL))
201 return;
202
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000203 if ((mwi->dwStyle & MCIWNDF_SHOWNAME) && mwi->lpName)
204 strcpyW(buffer, mwi->lpName);
205 else
206 *buffer = 0;
207
208 if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
209 {
210 static const WCHAR spaceW[] = {' ',0};
211 static const WCHAR l_braceW[] = {'(',0};
212
213 if (*buffer) strcatW(buffer, spaceW);
214 strcatW(buffer, l_braceW);
215 }
216
217 if (mwi->dwStyle & MCIWNDF_SHOWPOS)
218 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000219 WCHAR posW[64];
220
221 posW[0] = 0;
222 SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 64, (LPARAM)posW);
223 strcatW(buffer, posW);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000224 }
225
226 if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
227 {
228 static const WCHAR dashW[] = {' ','-',' ',0};
229 strcatW(buffer, dashW);
230 }
231
232 if (mwi->dwStyle & MCIWNDF_SHOWMODE)
233 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000234 WCHAR modeW[64];
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000235
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000236 modeW[0] = 0;
237 SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 64, (LPARAM)modeW);
238 strcatW(buffer, modeW);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000239 }
240
241 if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
242 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000243 static const WCHAR r_braceW[] = {')',0};
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000244 strcatW(buffer, r_braceW);
245 }
246
247 TRACE("=> '%s'\n", debugstr_w(buffer));
248 SetWindowTextW(mwi->hWnd, buffer);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000249}
250
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000251static LRESULT MCIWND_Create(HWND hWnd, LPCREATESTRUCTW cs)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000252{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000253 HWND hChld;
254 MCIWndInfo *mwi;
255 static const WCHAR buttonW[] = {'b','u','t','t','o','n',0};
Eric Pouecha3d3d402001-08-18 18:02:34 +0000256
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000257 mwi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*mwi));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000258 if (!mwi) return -1;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000259
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000260 SetWindowLongW(hWnd, 0, (LPARAM)mwi);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000261
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000262 mwi->dwStyle = cs->style;
Dmitry Timoshkov2ae461e2004-02-27 04:32:16 +0000263 /* There is no need to show stats if there is no caption */
264 if ((mwi->dwStyle & WS_CAPTION) != WS_CAPTION)
265 mwi->dwStyle &= ~MCIWNDF_SHOWALL;
266
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000267 mwi->hWnd = hWnd;
268 mwi->hwndOwner = cs->hwndParent;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000269 mwi->active_timer = 500;
270 mwi->inactive_timer = 2000;
271 mwi->mode = MCI_MODE_NOT_READY;
272 mwi->position = -1;
273 mwi->zoom = 100;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000274
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000275 if (!(mwi->dwStyle & MCIWNDF_NOMENU))
276 {
277 static const WCHAR menuW[] = {'M','e','n','u',0};
278
279 hChld = CreateWindowExW(0, buttonW, menuW, WS_CHILD|WS_VISIBLE, 32, cs->cy, 32, 32,
280 hWnd, (HMENU)CTL_MENU, cs->hInstance, 0L);
281 TRACE("Get Button2: %p\n", hChld);
282 }
283
284 if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
285 {
286 INITCOMMONCONTROLSEX init;
287 static const WCHAR playW[] = {'P','l','a','y',0};
288
289 /* adding the other elements: play/stop button, menu button, status */
290 hChld = CreateWindowExW(0, buttonW, playW, WS_CHILD|WS_VISIBLE, 0, cs->cy, 32, 32,
291 hWnd, (HMENU)CTL_PLAYSTOP, cs->hInstance, 0L);
292 TRACE("Get Button1: %p\n", hChld);
293
294 init.dwSize = sizeof(init);
295 init.dwICC = ICC_BAR_CLASSES;
296 InitCommonControlsEx(&init);
297
298 hChld = CreateWindowExW(0, TRACKBAR_CLASSW, NULL, WS_CHILD|WS_VISIBLE, 64, cs->cy, cs->cx - 64, 32,
299 hWnd, (HMENU)CTL_TRACKBAR, cs->hInstance, 0L);
300 TRACE("Get status: %p\n", hChld);
301 }
302
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000303 /* This sets the default window size */
304 SendMessageW(hWnd, MCI_CLOSE, 0, 0);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000305
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000306 if (cs->lpCreateParams)
307 {
308 LPARAM lParam;
309
310 /* MCI wnd class is prepared to be embedded as an MDI child window */
311 if (cs->dwExStyle & WS_EX_MDICHILD)
312 {
313 MDICREATESTRUCTW *mdics = (MDICREATESTRUCTW *)cs->lpCreateParams;
314 lParam = mdics->lParam;
315 }
316 else
317 lParam = (LPARAM)cs->lpCreateParams;
Dmitry Timoshkov2ae461e2004-02-27 04:32:16 +0000318
Dmitry Timoshkovbd6d7392004-02-27 21:24:47 +0000319 /* If it's our internal class pointer, file name is a unicode string */
Dmitry Timoshkov2ae461e2004-02-27 04:32:16 +0000320 if (cs->lpszClass == mciWndClassW)
321 SendMessageW(hWnd, MCIWNDM_OPENW, 0, lParam);
322 else
323 {
324 /* Otherwise let's try to figure out what string format is used */
325 HWND parent = cs->hwndParent;
326 if (!parent) parent = GetWindow(hWnd, GW_OWNER);
327
328 SendMessageW(hWnd, IsWindowUnicode(parent) ? MCIWNDM_OPENW : MCIWNDM_OPENA, 0, lParam);
329 }
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000330 }
331
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000332 return 0;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000333}
334
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000335static void MCIWND_ToggleState(MCIWndInfo *mwi)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000336{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000337 switch (SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 0, 0))
338 {
339 case MCI_MODE_NOT_READY:
340 case MCI_MODE_RECORD:
341 case MCI_MODE_SEEK:
342 case MCI_MODE_OPEN:
343 TRACE("Cannot do much...\n");
344 break;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000345
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000346 case MCI_MODE_PAUSE:
347 SendMessageW(mwi->hWnd, MCI_RESUME, 0, 0);
348 break;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000349
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000350 case MCI_MODE_PLAY:
351 SendMessageW(mwi->hWnd, MCI_PAUSE, 0, 0);
352 break;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000353
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000354 case MCI_MODE_STOP:
355 SendMessageW(mwi->hWnd, MCI_STOP, 0, 0);
356 break;
357 }
Eric Pouecha3d3d402001-08-18 18:02:34 +0000358}
359
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000360static LRESULT MCIWND_Command(MCIWndInfo *mwi, WPARAM wParam, LPARAM lParam)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000361{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000362 switch (LOWORD(wParam))
363 {
364 case CTL_PLAYSTOP: MCIWND_ToggleState(mwi); break;
365 case CTL_MENU:
366 case CTL_TRACKBAR:
367 default:
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000368 FIXME("support for command %04x not implement yet\n", LOWORD(wParam));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000369 }
370 return 0L;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000371}
372
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000373static void MCIWND_notify_media(MCIWndInfo *mwi)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000374{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000375 if (mwi->dwStyle & (MCIWNDF_NOTIFYMEDIAA | MCIWNDF_NOTIFYMEDIAW))
376 {
377 if (!mwi->lpName)
378 {
379 static const WCHAR empty_str[1];
380 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)empty_str);
381 }
382 else
383 {
384 if (mwi->dwStyle & MCIWNDF_NOTIFYANSI)
385 {
386 char *ansi_name;
387 int len;
388
389 len = WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, NULL, 0, NULL, NULL);
390 ansi_name = HeapAlloc(GetProcessHeap(), 0, len);
391 WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, ansi_name, len, NULL, NULL);
392
393 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)ansi_name);
394
395 HeapFree(GetProcessHeap(), 0, ansi_name);
396 }
397 else
398 SendMessageW(mwi->hwndOwner, MCIWNDM_NOTIFYMEDIA, (WPARAM)mwi->hWnd, (LPARAM)mwi->lpName);
399 }
400 }
Eric Pouecha3d3d402001-08-18 18:02:34 +0000401}
402
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000403static MCIERROR mci_generic_command(MCIWndInfo *mwi, UINT cmd)
404{
405 MCI_GENERIC_PARMS mci_generic;
406
407 mci_generic.dwCallback = 0;
408 mwi->lasterror = mciSendCommandW(mwi->mci, cmd, 0, (DWORD_PTR)&mci_generic);
409
410 if (mwi->lasterror)
411 return mwi->lasterror;
412
413 MCIWND_notify_mode(mwi);
414 MCIWND_UpdateState(mwi);
415 return 0;
416}
417
418static LRESULT mci_get_devcaps(MCIWndInfo *mwi, UINT cap)
419{
420 MCI_GETDEVCAPS_PARMS mci_devcaps;
421
422 mci_devcaps.dwItem = cap;
423 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
424 MCI_GETDEVCAPS_ITEM,
425 (DWORD_PTR)&mci_devcaps);
426 if (mwi->lasterror)
427 return 0;
428
429 return mci_devcaps.dwReturn;
430}
431
Dmitry Timoshkovb6c4bed2005-12-21 20:07:22 +0100432static LRESULT MCIWND_KeyDown(MCIWndInfo *mwi, UINT key)
433{
434 TRACE("%p, key %04x\n", mwi->hWnd, key);
435
436 switch(key)
437 {
438 case VK_ESCAPE:
439 SendMessageW(mwi->hWnd, MCI_STOP, 0, 0);
440 return 0;
441
442 default:
443 return 0;
444 }
445}
446
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000447static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
Eric Pouecha3d3d402001-08-18 18:02:34 +0000448{
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000449 MCIWndInfo *mwi;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000450
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000451 TRACE("%p %04x %08x %08lx\n", hWnd, wMsg, wParam, lParam);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000452
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000453 mwi = (MCIWndInfo*)GetWindowLongW(hWnd, 0);
Dmitry Timoshkov21272b32004-01-20 22:34:34 +0000454 if (!mwi && wMsg != WM_CREATE)
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000455 return DefWindowProcW(hWnd, wMsg, wParam, lParam);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000456
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000457 switch (wMsg)
458 {
Dmitry Timoshkov21272b32004-01-20 22:34:34 +0000459 case WM_CREATE:
460 MCIWND_Create(hWnd, (CREATESTRUCTW *)lParam);
461 break;
462
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000463 case WM_DESTROY:
464 if (mwi->uTimer)
465 KillTimer(hWnd, mwi->uTimer);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000466
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000467 if (mwi->mci)
468 SendMessageW(hWnd, MCI_CLOSE, 0, 0);
Eric Pouecha3d3d402001-08-18 18:02:34 +0000469
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000470 HeapFree(GetProcessHeap(), 0, mwi);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000471
472 DestroyWindow(GetDlgItem(hWnd, CTL_MENU));
473 DestroyWindow(GetDlgItem(hWnd, CTL_PLAYSTOP));
474 DestroyWindow(GetDlgItem(hWnd, CTL_TRACKBAR));
Dmitry Timoshkov21272b32004-01-20 22:34:34 +0000475 break;
Eric Pouecha3d3d402001-08-18 18:02:34 +0000476
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000477 case WM_PAINT:
478 {
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000479 MCI_DGV_UPDATE_PARMS mci_update;
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000480 PAINTSTRUCT ps;
481
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000482 mci_update.hDC = (wParam) ? (HDC)wParam : BeginPaint(hWnd, &ps);
483
484 mciSendCommandW(mwi->mci, MCI_UPDATE,
485 MCI_DGV_UPDATE_HDC | MCI_DGV_UPDATE_PAINT,
486 (DWORD_PTR)&mci_update);
487
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000488 if (!wParam) EndPaint(hWnd, &ps);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000489 return 1;
490 }
491
492 case WM_COMMAND:
493 return MCIWND_Command(mwi, wParam, lParam);
494
Dmitry Timoshkovb6c4bed2005-12-21 20:07:22 +0100495 case WM_KEYDOWN:
496 return MCIWND_KeyDown(mwi, wParam);
497
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000498 case WM_NCACTIVATE:
499 if (mwi->uTimer)
500 {
501 KillTimer(hWnd, mwi->uTimer);
502 mwi->uTimer = SetTimer(hWnd, 1, wParam ? mwi->active_timer : mwi->inactive_timer, NULL);
503 }
504 break;
505
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000506 case WM_TIMER:
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000507 MCIWND_UpdateState(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000508 return 0;
509
510 case WM_SIZE:
Dmitry Timoshkov21272b32004-01-20 22:34:34 +0000511 SetWindowPos(GetDlgItem(hWnd, CTL_PLAYSTOP), 0, 0, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
512 SetWindowPos(GetDlgItem(hWnd, CTL_MENU), 0, 32, HIWORD(lParam) - 32, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
513 SetWindowPos(GetDlgItem(hWnd, CTL_TRACKBAR), 0, 64, HIWORD(lParam) - 32, LOWORD(lParam) - 64, 32, SWP_NOACTIVATE);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000514
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000515 if (!(mwi->dwStyle & MCIWNDF_NOAUTOSIZEMOVIE))
516 {
517 RECT rc;
518
519 rc.left = rc.top = 0;
520 rc.right = LOWORD(lParam);
521 rc.bottom = HIWORD(lParam);
522 if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
523 rc.bottom -= 32; /* subtract the height of the playbar */
524 SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc);
525 }
Dmitry Timoshkov21272b32004-01-20 22:34:34 +0000526 MCIWND_notify_size(mwi);
527 break;
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000528
529 case MM_MCINOTIFY:
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000530 MCIWND_notify_mode(mwi);
531 MCIWND_UpdateState(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000532 return 0;
533
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000534 case MCIWNDM_OPENA:
535 {
536 UNICODE_STRING nameW;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000537 TRACE("MCIWNDM_OPENA %s\n", debugstr_a((LPSTR)lParam));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000538 RtlCreateUnicodeStringFromAsciiz(&nameW, (LPCSTR)lParam);
539 lParam = (LPARAM)nameW.Buffer;
540 }
541 /* fall through */
542 case MCIWNDM_OPENW:
543 {
544 RECT rc;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000545 HCURSOR hCursor;
546 MCI_OPEN_PARMSW mci_open;
547 MCI_GETDEVCAPS_PARMS mci_devcaps;
548 WCHAR aliasW[64];
549 WCHAR drv_name[MAX_PATH];
550 static const WCHAR formatW[] = {'%','d',0};
551 static const WCHAR mci32W[] = {'m','c','i','3','2',0};
552 static const WCHAR system_iniW[] = {'s','y','s','t','e','m','.','i','n','i',0};
553
554 TRACE("MCIWNDM_OPENW %s\n", debugstr_w((LPWSTR)lParam));
555
556 if (wParam == MCIWNDOPENF_NEW)
557 {
558 SendMessageW(hWnd, MCIWNDM_NEWW, 0, lParam);
559 goto end_of_mci_open;
560 }
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000561
562 if (mwi->uTimer)
563 {
564 KillTimer(hWnd, mwi->uTimer);
565 mwi->uTimer = 0;
566 }
567
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000568 hCursor = LoadCursorW(0, (LPWSTR)IDC_WAIT);
569 hCursor = SetCursor(hCursor);
570
571 mci_open.lpstrElementName = (LPWSTR)lParam;
572 wsprintfW(aliasW, formatW, (int)hWnd + 1);
573 mci_open.lpstrAlias = aliasW;
574 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_OPEN,
575 MCI_OPEN_ELEMENT | MCI_OPEN_ALIAS | MCI_WAIT,
576 (DWORD_PTR)&mci_open);
577 SetCursor(hCursor);
578
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000579 if (mwi->lasterror && !(mwi->dwStyle & MCIWNDF_NOERRORDLG))
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000580 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000581 /* FIXME: get the caption from resources */
582 static const WCHAR caption[] = {'M','C','I',' ','E','r','r','o','r',0};
583 WCHAR error_str[MAXERRORLENGTH];
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000584
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000585 mciGetErrorStringW(mwi->lasterror, error_str, MAXERRORLENGTH);
586 MessageBoxW(hWnd, error_str, caption, MB_ICONEXCLAMATION | MB_OK);
587 MCIWND_notify_error(mwi);
588 goto end_of_mci_open;
589 }
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000590
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000591 mwi->mci = mci_open.wDeviceID;
592 mwi->alias = (int)hWnd + 1;
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000593
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000594 mwi->lpName = HeapAlloc(GetProcessHeap(), 0, (strlenW((LPWSTR)lParam) + 1) * sizeof(WCHAR));
595 strcpyW(mwi->lpName, (LPWSTR)lParam);
596
597 MCIWND_UpdateState(mwi);
598
599 mci_devcaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
600 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
601 MCI_GETDEVCAPS_ITEM,
602 (DWORD_PTR)&mci_devcaps);
603 if (mwi->lasterror)
604 {
605 MCIWND_notify_error(mwi);
606 goto end_of_mci_open;
607 }
608
609 mwi->dev_type = mci_devcaps.dwReturn;
610
611 drv_name[0] = 0;
612 SendMessageW(hWnd, MCIWNDM_GETDEVICEW, 256, (LPARAM)drv_name);
613 if (drv_name[0] && GetPrivateProfileStringW(mci32W, drv_name, NULL,
614 drv_name, MAX_PATH, system_iniW))
615 mwi->hdrv = OpenDriver(drv_name, NULL, 0);
616
617 if (mwi->dev_type == MCI_DEVTYPE_DIGITAL_VIDEO)
618 {
619 MCI_DGV_WINDOW_PARMSW mci_window;
620
621 mci_window.hWnd = hWnd;
622 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WINDOW,
623 MCI_DGV_WINDOW_HWND,
624 (DWORD_PTR)&mci_window);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000625 if (mwi->lasterror)
626 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000627 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000628 goto end_of_mci_open;
629 }
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000630 }
631
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000632 if (SendMessageW(hWnd, MCIWNDM_GET_DEST, 0, (LPARAM)&rc) == 0)
633 {
634 mwi->size.cx = rc.right - rc.left;
635 mwi->size.cy = rc.bottom - rc.top;
636
637 rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100);
638 rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100);
639 SendMessageW(hWnd, MCIWNDM_PUT_DEST, 0, (LPARAM)&rc);
640 }
641 else
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000642 {
643 GetClientRect(hWnd, &rc);
644 rc.bottom = rc.top;
645 }
646
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000647 if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
648 rc.bottom += 32; /* add the height of the playbar */
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000649 AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000650 SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000651 rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000652
653 SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000654 SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1,
655 SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0));
656 mwi->uTimer = SetTimer(hWnd, 1, mwi->active_timer, NULL);
657
658 MCIWND_notify_media(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000659
660end_of_mci_open:
661 if (wMsg == MCIWNDM_OPENA)
662 HeapFree(GetProcessHeap(), 0, (void *)lParam);
663 return mwi->lasterror;
664 }
665
666 case MCIWNDM_GETDEVICEID:
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000667 TRACE("MCIWNDM_GETDEVICEID\n");
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000668 return mwi->mci;
669
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000670 case MCIWNDM_GETALIAS:
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000671 TRACE("MCIWNDM_GETALIAS\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000672 return mwi->alias;
673
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000674 case MCIWNDM_GET_SOURCE:
675 {
676 MCI_DGV_RECT_PARMS mci_rect;
677
678 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE,
679 MCI_DGV_WHERE_SOURCE,
680 (DWORD_PTR)&mci_rect);
681 if (mwi->lasterror)
682 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000683 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000684 return mwi->lasterror;
685 }
686 *(RECT *)lParam = mci_rect.rc;
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000687 TRACE("MCIWNDM_GET_SOURCE: %s\n", wine_dbgstr_rect(&mci_rect.rc));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000688 return 0;
689 }
690
691 case MCIWNDM_GET_DEST:
692 {
693 MCI_DGV_RECT_PARMS mci_rect;
694
695 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_WHERE,
696 MCI_DGV_WHERE_DESTINATION,
697 (DWORD_PTR)&mci_rect);
698 if (mwi->lasterror)
699 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000700 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000701 return mwi->lasterror;
702 }
703 *(RECT *)lParam = mci_rect.rc;
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000704 TRACE("MCIWNDM_GET_DEST: %s\n", wine_dbgstr_rect(&mci_rect.rc));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000705 return 0;
706 }
707
708 case MCIWNDM_PUT_SOURCE:
709 {
710 MCI_DGV_PUT_PARMS mci_put;
711
712 mci_put.rc = *(RECT *)lParam;
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000713 TRACE("MCIWNDM_PUT_SOURCE: %s\n", wine_dbgstr_rect(&mci_put.rc));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000714 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
715 MCI_DGV_PUT_SOURCE,
716 (DWORD_PTR)&mci_put);
717 if (mwi->lasterror)
718 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000719 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000720 return mwi->lasterror;
721 }
722 return 0;
723 }
724
725 case MCIWNDM_PUT_DEST:
726 {
727 MCI_DGV_PUT_PARMS mci_put;
728
729 mci_put.rc = *(RECT *)lParam;
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000730 TRACE("MCIWNDM_PUT_DEST: %s\n", wine_dbgstr_rect(&mci_put.rc));
731
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000732 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PUT,
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000733 MCI_DGV_PUT_DESTINATION | MCI_DGV_RECT,
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000734 (DWORD_PTR)&mci_put);
735 if (mwi->lasterror)
736 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000737 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000738 return mwi->lasterror;
739 }
740 return 0;
741 }
742
743 case MCIWNDM_GETLENGTH:
744 {
745 MCI_STATUS_PARMS mci_status;
746
747 mci_status.dwItem = MCI_STATUS_LENGTH;
748 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
749 MCI_STATUS_ITEM,
750 (DWORD_PTR)&mci_status);
751 if (mwi->lasterror)
752 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000753 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000754 return 0;
755 }
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000756 TRACE("MCIWNDM_GETLENGTH: %ld\n", mci_status.dwReturn);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000757 return mci_status.dwReturn;
758 }
759
760 case MCIWNDM_GETSTART:
761 {
762 MCI_STATUS_PARMS mci_status;
763
764 mci_status.dwItem = MCI_STATUS_POSITION;
765 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
766 MCI_STATUS_ITEM | MCI_STATUS_START,
767 (DWORD_PTR)&mci_status);
768 if (mwi->lasterror)
769 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000770 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000771 return 0;
772 }
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000773 TRACE("MCIWNDM_GETSTART: %ld\n", mci_status.dwReturn);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000774 return mci_status.dwReturn;
775 }
776
777 case MCIWNDM_GETEND:
778 {
779 LRESULT start, length;
780
781 start = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
782 length = SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000783 TRACE("MCIWNDM_GETEND: %ld\n", start + length);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000784 return (start + length);
785 }
786
787 case MCIWNDM_GETPOSITIONA:
788 case MCIWNDM_GETPOSITIONW:
789 {
790 MCI_STATUS_PARMS mci_status;
791
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000792 TRACE("MCIWNDM_GETPOSITION\n");
793
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000794 /* get position string if requested */
795 if (wParam && lParam)
796 {
797 if (wMsg == MCIWNDM_GETPOSITIONA)
798 {
799 char cmd[64];
800
801 wsprintfA(cmd, "status %d position", mwi->alias);
802 mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
803 }
804 else
805 {
806
807 WCHAR cmdW[64];
808 static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','p','o','s','i','t','i','o','n',0};
809
810 wsprintfW(cmdW, formatW, mwi->alias);
811 mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
812 }
813
814 if (mwi->lasterror)
815 return 0;
816 }
817
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000818 mci_status.dwItem = MCI_STATUS_POSITION;
819 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
820 MCI_STATUS_ITEM,
821 (DWORD_PTR)&mci_status);
822 if (mwi->lasterror)
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000823 return 0;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000824
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000825 return mci_status.dwReturn;
826 }
827
828 case MCIWNDM_GETMODEA:
829 case MCIWNDM_GETMODEW:
830 {
831 MCI_STATUS_PARMS mci_status;
832
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000833 TRACE("MCIWNDM_GETMODE\n");
834
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000835 if (!mwi->mci)
836 return MCI_MODE_NOT_READY;
837
838 /* get mode string if requested */
839 if (wParam && lParam)
840 {
841 if (wMsg == MCIWNDM_GETMODEA)
842 {
843 char cmd[64];
844
845 wsprintfA(cmd, "status %d mode", mwi->alias);
846 mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
847 }
848 else
849 {
850
851 WCHAR cmdW[64];
852 static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','m','o','d','e',0};
853
854 wsprintfW(cmdW, formatW, mwi->alias);
855 mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
856 }
857
858 if (mwi->lasterror)
859 return MCI_MODE_NOT_READY;
860 }
861
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000862 mci_status.dwItem = MCI_STATUS_MODE;
863 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
864 MCI_STATUS_ITEM,
865 (DWORD_PTR)&mci_status);
866 if (mwi->lasterror)
867 return MCI_MODE_NOT_READY;
868
869 return mci_status.dwReturn;
870 }
871
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000872 case MCIWNDM_PLAYFROM:
873 {
874 MCI_PLAY_PARMS mci_play;
875
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000876 TRACE("MCIWNDM_PLAYFROM %08lx\n", lParam);
877
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000878 mci_play.dwCallback = (DWORD_PTR)hWnd;
879 mci_play.dwFrom = lParam;
880 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
881 MCI_FROM | MCI_NOTIFY,
882 (DWORD_PTR)&mci_play);
883 if (mwi->lasterror)
884 {
885 MCIWND_notify_error(mwi);
886 return mwi->lasterror;
887 }
888
889 MCIWND_notify_mode(mwi);
890 MCIWND_UpdateState(mwi);
891 return 0;
892 }
893
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000894 case MCIWNDM_PLAYTO:
895 {
896 MCI_PLAY_PARMS mci_play;
897
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000898 TRACE("MCIWNDM_PLAYTO %08lx\n", lParam);
899
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000900 mci_play.dwCallback = (DWORD_PTR)hWnd;
901 mci_play.dwTo = lParam;
902 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000903 MCI_TO | MCI_NOTIFY,
904 (DWORD_PTR)&mci_play);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000905 if (mwi->lasterror)
906 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000907 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000908 return mwi->lasterror;
909 }
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000910
911 MCIWND_notify_mode(mwi);
912 MCIWND_UpdateState(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000913 return 0;
914 }
915
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000916 case MCIWNDM_PLAYREVERSE:
917 {
918 MCI_PLAY_PARMS mci_play;
919 DWORD flags = MCI_NOTIFY;
920
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000921 TRACE("MCIWNDM_PLAYREVERSE %08lx\n", lParam);
922
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000923 mci_play.dwCallback = (DWORD_PTR)hWnd;
924 mci_play.dwFrom = lParam;
925 switch (mwi->dev_type)
926 {
927 default:
928 case MCI_DEVTYPE_ANIMATION:
929 flags |= MCI_ANIM_PLAY_REVERSE;
930 break;
931
932 case MCI_DEVTYPE_DIGITAL_VIDEO:
933 flags |= MCI_DGV_PLAY_REVERSE;
934 break;
935
936#ifdef MCI_VCR_PLAY_REVERSE
937 case MCI_DEVTYPE_VCR:
938 flags |= MCI_VCR_PLAY_REVERSE;
939 break;
940#endif
941
942 case MCI_DEVTYPE_VIDEODISC:
943 flags |= MCI_VD_PLAY_REVERSE;
944 break;
945
946 }
947 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_PLAY,
948 flags, (DWORD_PTR)&mci_play);
949 if (mwi->lasterror)
950 {
951 MCIWND_notify_error(mwi);
952 return mwi->lasterror;
953 }
954
955 MCIWND_notify_mode(mwi);
956 MCIWND_UpdateState(mwi);
957 return 0;
958 }
959
960 case MCIWNDM_GETERRORA:
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000961 mciGetErrorStringA(mwi->lasterror, (LPSTR)lParam, wParam);
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000962 TRACE("MCIWNDM_GETERRORA: %s\n", debugstr_an((LPSTR)lParam, wParam));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000963 return mwi->lasterror;
964
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000965 case MCIWNDM_GETERRORW:
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000966 mciGetErrorStringW(mwi->lasterror, (LPWSTR)lParam, wParam);
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000967 TRACE("MCIWNDM_GETERRORW: %s\n", debugstr_wn((LPWSTR)lParam, wParam));
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000968 return mwi->lasterror;
969
970 case MCIWNDM_SETOWNER:
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000971 TRACE("MCIWNDM_SETOWNER %p\n", (HWND)wParam);
Dmitry Timoshkov06464992003-12-15 20:17:11 +0000972 mwi->hwndOwner = (HWND)wParam;
973 return 0;
974
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000975 case MCIWNDM_SENDSTRINGA:
976 {
977 UNICODE_STRING stringW;
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000978
979 TRACE("MCIWNDM_SENDSTRINGA %s\n", debugstr_a((LPCSTR)lParam));
980
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000981 RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
982 lParam = (LPARAM)stringW.Buffer;
983 }
984 /* fall through */
985 case MCIWNDM_SENDSTRINGW:
986 {
987 WCHAR *cmdW, *p;
988
Dmitry Timoshkov19924762004-03-01 23:38:25 +0000989 TRACE("MCIWNDM_SENDSTRINGW %s\n", debugstr_w((LPCWSTR)lParam));
990
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +0000991 p = strchrW((LPCWSTR)lParam, ' ');
992 if (p)
993 {
994 static const WCHAR formatW[] = {'%','d',' ',0};
995 int len, pos;
996
997 pos = p - (WCHAR *)lParam + 1;
998 len = lstrlenW((LPCWSTR)lParam) + 64;
999
1000 cmdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1001
1002 memcpy(cmdW, (void *)lParam, pos * sizeof(WCHAR));
1003 wsprintfW(cmdW + pos, formatW, mwi->alias);
1004 strcatW(cmdW, (WCHAR *)lParam + pos);
1005 }
1006 else
1007 cmdW = (LPWSTR)lParam;
1008
1009 mwi->lasterror = mciSendStringW(cmdW, mwi->return_string,
1010 sizeof(mwi->return_string)/sizeof(mwi->return_string[0]),
1011 0);
1012 if (mwi->lasterror)
1013 MCIWND_notify_error(mwi);
1014
1015 if (cmdW != (LPWSTR)lParam)
1016 HeapFree(GetProcessHeap(), 0, cmdW);
1017
1018 if (wMsg == MCIWNDM_SENDSTRINGA)
1019 HeapFree(GetProcessHeap(), 0, (void *)lParam);
1020
1021 MCIWND_UpdateState(mwi);
1022 return mwi->lasterror;
1023 }
1024
1025 case MCIWNDM_RETURNSTRINGA:
1026 WideCharToMultiByte(CP_ACP, 0, mwi->return_string, -1, (LPSTR)lParam, wParam, NULL, NULL);
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001027 TRACE("MCIWNDM_RETURNTRINGA %s\n", debugstr_an((LPSTR)lParam, wParam));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001028 return mwi->lasterror;
1029
1030 case MCIWNDM_RETURNSTRINGW:
Peter Berg Larsen6e3bcb52005-04-18 10:30:55 +00001031 lstrcpynW((LPWSTR)lParam, mwi->return_string, wParam);
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001032 TRACE("MCIWNDM_RETURNTRINGW %s\n", debugstr_wn((LPWSTR)lParam, wParam));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001033 return mwi->lasterror;
1034
1035 case MCIWNDM_SETTIMERS:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001036 TRACE("MCIWNDM_SETTIMERS active %d ms, inactive %d ms\n", (int)wParam, (int)lParam);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001037 mwi->active_timer = (WORD)wParam;
1038 mwi->inactive_timer = (WORD)lParam;
1039 return 0;
1040
1041 case MCIWNDM_SETACTIVETIMER:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001042 TRACE("MCIWNDM_SETACTIVETIMER %d ms\n", (int)wParam);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001043 mwi->active_timer = (WORD)wParam;
1044 return 0;
1045
1046 case MCIWNDM_SETINACTIVETIMER:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001047 TRACE("MCIWNDM_SETINACTIVETIMER %d ms\n", (int)wParam);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001048 mwi->inactive_timer = (WORD)wParam;
1049 return 0;
1050
1051 case MCIWNDM_GETACTIVETIMER:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001052 TRACE("MCIWNDM_GETACTIVETIMER: %d ms\n", mwi->active_timer);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001053 return mwi->active_timer;
1054
1055 case MCIWNDM_GETINACTIVETIMER:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001056 TRACE("MCIWNDM_GETINACTIVETIMER: %d ms\n", mwi->inactive_timer);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001057 return mwi->inactive_timer;
1058
1059 case MCIWNDM_CHANGESTYLES:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001060 TRACE("MCIWNDM_CHANGESTYLES mask %08x, set %08lx\n", wParam, lParam);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001061 /* FIXME: update the visual window state as well:
1062 * add/remove trackbar, autosize, etc.
1063 */
1064 mwi->dwStyle &= ~wParam;
1065 mwi->dwStyle |= lParam & wParam;
1066 return 0;
1067
1068 case MCIWNDM_GETSTYLES:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001069 TRACE("MCIWNDM_GETSTYLES: %08lx\n", mwi->dwStyle & 0xffff);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001070 return mwi->dwStyle & 0xffff;
1071
1072 case MCIWNDM_GETDEVICEA:
1073 {
1074 MCI_SYSINFO_PARMSA mci_sysinfo;
1075
1076 mci_sysinfo.lpstrReturn = (LPSTR)lParam;
1077 mci_sysinfo.dwRetSize = wParam;
1078 mwi->lasterror = mciSendCommandA(mwi->mci, MCI_SYSINFO,
1079 MCI_SYSINFO_INSTALLNAME,
1080 (DWORD_PTR)&mci_sysinfo);
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001081 TRACE("MCIWNDM_GETDEVICEA: %s\n", debugstr_an((LPSTR)lParam, wParam));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001082 return 0;
1083 }
1084
1085 case MCIWNDM_GETDEVICEW:
1086 {
1087 MCI_SYSINFO_PARMSW mci_sysinfo;
1088
1089 mci_sysinfo.lpstrReturn = (LPWSTR)lParam;
1090 mci_sysinfo.dwRetSize = wParam;
1091 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SYSINFO,
1092 MCI_SYSINFO_INSTALLNAME,
1093 (DWORD_PTR)&mci_sysinfo);
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001094 TRACE("MCIWNDM_GETDEVICEW: %s\n", debugstr_wn((LPWSTR)lParam, wParam));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001095 return 0;
1096 }
1097
1098 case MCIWNDM_VALIDATEMEDIA:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001099 TRACE("MCIWNDM_VALIDATEMEDIA\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001100 if (mwi->mci)
1101 {
1102 SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
1103 SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0);
1104 }
1105 return 0;
1106
1107 case MCIWNDM_GETFILENAMEA:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001108 TRACE("MCIWNDM_GETFILENAMEA: %s\n", debugstr_w(mwi->lpName));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001109 if (mwi->lpName)
1110 WideCharToMultiByte(CP_ACP, 0, mwi->lpName, -1, (LPSTR)lParam, wParam, NULL, NULL);
1111 return 0;
1112
1113 case MCIWNDM_GETFILENAMEW:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001114 TRACE("MCIWNDM_GETFILENAMEW: %s\n", debugstr_w(mwi->lpName));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001115 if (mwi->lpName)
Peter Berg Larsen6e3bcb52005-04-18 10:30:55 +00001116 lstrcpynW((LPWSTR)lParam, mwi->lpName, wParam);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001117 return 0;
1118
1119 case MCIWNDM_GETTIMEFORMATA:
1120 case MCIWNDM_GETTIMEFORMATW:
1121 {
1122 MCI_STATUS_PARMS mci_status;
1123
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001124 TRACE("MCIWNDM_GETTIMEFORMAT %08x %08lx\n", wParam, lParam);
1125
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001126 /* get format string if requested */
1127 if (wParam && lParam)
1128 {
1129 if (wMsg == MCIWNDM_GETTIMEFORMATA)
1130 {
1131 char cmd[64];
1132
1133 wsprintfA(cmd, "status %d time format", mwi->alias);
1134 mwi->lasterror = mciSendStringA(cmd, (LPSTR)lParam, wParam, 0);
1135 if (mwi->lasterror)
1136 return 0;
1137 }
1138 else
1139 {
1140 WCHAR cmdW[64];
1141 static const WCHAR formatW[] = {'s','t','a','t','u','s',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',0};
1142
1143 wsprintfW(cmdW, formatW, mwi->alias);
1144 mwi->lasterror = mciSendStringW(cmdW, (LPWSTR)lParam, wParam, 0);
1145 if (mwi->lasterror)
1146 return 0;
1147 }
1148 }
1149
1150 mci_status.dwItem = MCI_STATUS_TIME_FORMAT ;
1151 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STATUS,
1152 MCI_STATUS_ITEM,
1153 (DWORD_PTR)&mci_status);
1154 if (mwi->lasterror)
1155 return 0;
1156
1157 return mci_status.dwReturn;
1158 }
1159
1160 case MCIWNDM_SETTIMEFORMATA:
1161 {
1162 UNICODE_STRING stringW;
1163
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001164 TRACE("MCIWNDM_SETTIMEFORMATA %s\n", debugstr_a((LPSTR)lParam));
1165
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001166 RtlCreateUnicodeStringFromAsciiz(&stringW, (LPCSTR)lParam);
1167 lParam = (LPARAM)stringW.Buffer;
1168 }
1169 /* fall through */
1170 case MCIWNDM_SETTIMEFORMATW:
1171 {
1172 static const WCHAR formatW[] = {'s','e','t',' ','%','d',' ','t','i','m','e',' ','f','o','r','m','a','t',' ',0};
1173 WCHAR *cmdW;
1174
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001175 TRACE("MCIWNDM_SETTIMEFORMATW %s\n", debugstr_w((LPWSTR)lParam));
1176
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001177 if (mwi->mci)
1178 {
1179 cmdW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW((LPCWSTR)lParam) + 64) * sizeof(WCHAR));
1180 wsprintfW(cmdW, formatW, mwi->alias);
1181 strcatW(cmdW, (WCHAR *)lParam);
1182
1183 mwi->lasterror = mciSendStringW(cmdW, NULL, 0, 0);
Dmitry Timoshkov2b9d1382004-01-02 01:48:15 +00001184
1185 /* fix the range tracking according to the new time format */
1186 if (!mwi->lasterror)
1187 SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMAX, 1,
1188 SendMessageW(hWnd, MCIWNDM_GETLENGTH, 0, 0));
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001189 }
1190
1191 if (wMsg == MCIWNDM_SETTIMEFORMATA)
1192 HeapFree(GetProcessHeap(), 0, (void *)lParam);
1193
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001194 return 0;
1195 }
1196
1197 case MCIWNDM_CAN_PLAY:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001198 TRACE("MCIWNDM_CAN_PLAY\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001199 if (mwi->mci)
1200 return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_PLAY);
1201 return 0;
1202
1203 case MCIWNDM_CAN_RECORD:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001204 TRACE("MCIWNDM_CAN_RECORD\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001205 if (mwi->mci)
1206 return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_RECORD);
1207 return 0;
1208
1209 case MCIWNDM_CAN_SAVE:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001210 TRACE("MCIWNDM_CAN_SAVE\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001211 if (mwi->mci)
1212 return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_SAVE);
1213 return 0;
1214
1215 case MCIWNDM_CAN_EJECT:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001216 TRACE("MCIWNDM_CAN_EJECT\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001217 if (mwi->mci)
1218 return mci_get_devcaps(mwi, MCI_GETDEVCAPS_CAN_EJECT);
1219 return 0;
1220
1221 case MCIWNDM_CAN_WINDOW:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001222 TRACE("MCIWNDM_CAN_WINDOW\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001223 switch (mwi->dev_type)
1224 {
1225 case MCI_DEVTYPE_ANIMATION:
1226 case MCI_DEVTYPE_DIGITAL_VIDEO:
1227 case MCI_DEVTYPE_OVERLAY:
1228 return 1;
1229 }
1230 return 0;
1231
1232 case MCIWNDM_CAN_CONFIG:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001233 TRACE("MCIWNDM_CAN_CONFIG\n");
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001234 if (mwi->hdrv)
1235 return SendDriverMessage(mwi->hdrv, DRV_QUERYCONFIGURE, 0, 0);
1236 return 0;
1237
1238 case MCIWNDM_SETZOOM:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001239 TRACE("MCIWNDM_SETZOOM %ld\n", lParam);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001240 mwi->zoom = lParam;
1241
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001242 if (mwi->mci && !(mwi->dwStyle & MCIWNDF_NOAUTOSIZEWINDOW))
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001243 {
1244 RECT rc;
1245
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001246 rc.left = rc.top = 0;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001247 rc.right = MulDiv(mwi->size.cx, mwi->zoom, 100);
1248 rc.bottom = MulDiv(mwi->size.cy, mwi->zoom, 100);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001249
1250 if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
1251 rc.bottom += 32; /* add the height of the playbar */
1252 AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
1253 SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
1254 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1255 }
1256 return 0;
1257
1258 case MCIWNDM_GETZOOM:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001259 TRACE("MCIWNDM_GETZOOM: %d\n", mwi->zoom);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001260 return mwi->zoom;
1261
1262 case MCIWNDM_EJECT:
1263 {
1264 MCI_SET_PARMS mci_set;
1265
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001266 TRACE("MCIWNDM_EJECT\n");
1267
Dmitry Timoshkov2b9d1382004-01-02 01:48:15 +00001268 mci_set.dwCallback = (DWORD_PTR)hWnd;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001269 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SET,
1270 MCI_SET_DOOR_OPEN | MCI_NOTIFY,
1271 (DWORD_PTR)&mci_set);
Dmitry Timoshkov2b9d1382004-01-02 01:48:15 +00001272 MCIWND_notify_mode(mwi);
1273 MCIWND_UpdateState(mwi);
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001274 return mwi->lasterror;
1275 }
1276
1277 case MCIWNDM_SETVOLUME:
1278 case MCIWNDM_GETVOLUME:
1279 case MCIWNDM_SETSPEED:
1280 case MCIWNDM_GETSPEED:
1281 case MCIWNDM_SETREPEAT:
1282 case MCIWNDM_GETREPEAT:
1283 case MCIWNDM_REALIZE:
1284 case MCIWNDM_GETPALETTE:
1285 case MCIWNDM_SETPALETTE:
1286 case MCIWNDM_NEWA:
1287 case MCIWNDM_NEWW:
1288 case MCIWNDM_PALETTEKICK:
1289 case MCIWNDM_OPENINTERFACE:
1290 FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER);
1291 return 0;
1292
Dmitry Timoshkovbe6d0142003-12-31 19:00:03 +00001293 case MCI_PLAY:
1294 {
1295 LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
1296 return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end);
1297 }
1298
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001299 case MCI_SEEK:
1300 {
1301 MCI_SEEK_PARMS mci_seek;
1302
1303 switch (lParam)
1304 {
1305 case MCIWND_START:
1306 lParam = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
1307 break;
1308
1309 case MCIWND_END:
1310 lParam = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
1311 break;
1312 }
1313
1314 mci_seek.dwTo = lParam;
1315 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SEEK,
1316 MCI_TO, (DWORD_PTR)&mci_seek);
1317 if (mwi->lasterror)
1318 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001319 MCIWND_notify_error(mwi);
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001320 return mwi->lasterror;
1321 }
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001322 /* update window to reflect the state */
1323 InvalidateRect(hWnd, NULL, TRUE);
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001324 return 0;
1325 }
1326
1327 case MCI_CLOSE:
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001328 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001329 RECT rc;
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001330 MCI_GENERIC_PARMS mci_generic;
1331
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001332 if (mwi->hdrv)
Dmitry Timoshkovbe6d0142003-12-31 19:00:03 +00001333 {
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001334 CloseDriver(mwi->hdrv, 0, 0);
1335 mwi->hdrv = 0;
Dmitry Timoshkovbe6d0142003-12-31 19:00:03 +00001336 }
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001337
1338 if (mwi->mci)
1339 {
1340 mci_generic.dwCallback = 0;
1341 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE,
1342 0, (DWORD_PTR)&mci_generic);
1343 mwi->mci = 0;
1344 }
1345
1346 mwi->mode = MCI_MODE_NOT_READY;
1347 mwi->position = -1;
1348
Michael Stefaniuc5ad7d852004-12-23 17:06:43 +00001349 HeapFree(GetProcessHeap(), 0, mwi->lpName);
1350 mwi->lpName = NULL;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001351 MCIWND_UpdateState(mwi);
1352
1353 GetClientRect(hWnd, &rc);
1354 rc.bottom = rc.top;
1355 if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
1356 rc.bottom += 32; /* add the height of the playbar */
1357 AdjustWindowRect(&rc, GetWindowLongW(hWnd, GWL_STYLE), FALSE);
1358 SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
1359 rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1360
1361 MCIWND_notify_media(mwi);
Dmitry Timoshkovbe6d0142003-12-31 19:00:03 +00001362 return 0;
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001363 }
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001364
1365 case MCI_PAUSE:
1366 case MCI_STEP:
1367 case MCI_STOP:
1368 case MCI_RESUME:
Dmitry Timoshkov19924762004-03-01 23:38:25 +00001369 mci_generic_command(mwi, wMsg);
1370 if (wMsg == MCI_STEP && !mwi->lasterror)
1371 {
1372 /* update window to reflect the state */
1373 InvalidateRect(hWnd, NULL, TRUE);
1374 }
1375 return mwi->lasterror;
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001376
1377 case MCI_CONFIGURE:
1378 if (mwi->hdrv)
1379 SendDriverMessage(mwi->hdrv, DRV_CONFIGURE, (LPARAM)hWnd, 0);
1380 return 0;
1381
1382 case MCI_BREAK:
1383 case MCI_CAPTURE:
1384 case MCI_COPY:
1385 case MCI_CUE:
1386 case MCI_CUT:
1387 case MCI_DELETE:
1388 case MCI_ESCAPE:
1389 case MCI_FREEZE:
1390 case MCI_GETDEVCAPS:
1391 /*case MCI_INDEX:*/
1392 case MCI_INFO:
1393 case MCI_LIST:
1394 case MCI_LOAD:
1395 /*case MCI_MARK:*/
1396 case MCI_MONITOR:
1397 case MCI_OPEN:
1398 case MCI_PASTE:
1399 case MCI_PUT:
1400 case MCI_QUALITY:
1401 case MCI_REALIZE:
1402 case MCI_RECORD:
1403 case MCI_RESERVE:
1404 case MCI_RESTORE:
1405 case MCI_SAVE:
1406 case MCI_SET:
1407 case MCI_SETAUDIO:
1408 /*case MCI_SETTIMECODE:*/
1409 /*case MCI_SETTUNER:*/
1410 case MCI_SETVIDEO:
1411 case MCI_SIGNAL:
1412 case MCI_SPIN:
1413 case MCI_STATUS:
1414 case MCI_SYSINFO:
1415 case MCI_UNDO:
1416 case MCI_UNFREEZE:
1417 case MCI_UPDATE:
1418 case MCI_WHERE:
1419 case MCI_WINDOW:
1420 FIXME("support for MCI_ command %04x not implemented\n", wMsg);
1421 return 0;
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001422 }
1423
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001424 if (wMsg >= WM_USER)
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001425 {
Dmitry Timoshkov853329b2003-12-10 02:10:18 +00001426 FIXME("support for MCIWNDM_ message WM_USER+%d not implemented\n", wMsg - WM_USER);
1427 return 0;
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001428 }
Dmitry Timoshkov853329b2003-12-10 02:10:18 +00001429
Dmitry Timoshkovcd61ce82004-01-01 00:12:13 +00001430 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
1431 return DefMDIChildProcW(hWnd, wMsg, wParam, lParam);
1432
Dmitry Timoshkov06464992003-12-15 20:17:11 +00001433 return DefWindowProcW(hWnd, wMsg, wParam, lParam);
Eric Pouecha3d3d402001-08-18 18:02:34 +00001434}