2 * Copyright 2000 Eric Pouech
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.
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.
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/mmsystem16.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mci);
44 static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2);
46 #define CTL_PLAYSTOP 0x3200
47 #define CTL_MENU 0x3201
48 #define CTL_TRACKBAR 0x3202
50 /***********************************************************************
51 * MCIWndRegisterClass [MSVFW32.@]
53 BOOL WINAPI MCIWndRegisterClass(HINSTANCE hInst)
57 /* since window creation will also require some common controls, init them */
61 wc.lpfnWndProc = MCIWndProc;
63 wc.cbWndExtra = sizeof(MCIWndInfo*);
68 wc.lpszMenuName = NULL;
69 wc.lpszClassName = "MCIWndClass";
71 return RegisterClassA(&wc);
75 /***********************************************************************
76 * MCIWndCreate [MSVFW32.@]
77 * MCIWndCreateA [MSVFW32.@]
79 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
80 DWORD dwStyle, LPCSTR szFile)
85 TRACE("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, szFile);
87 MCIWndRegisterClass(hInstance);
89 mwi = HeapAlloc(GetProcessHeap(), 0, sizeof(*mwi));
92 mwi->dwStyle = dwStyle;
93 mwi->lpName = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(szFile) + 1), szFile);
96 wndStyle = ((hwndParent) ? (WS_CHILD|WS_BORDER) : WS_OVERLAPPEDWINDOW) |
97 WS_VISIBLE | (dwStyle & 0xFFFF0000);
99 if (CreateWindowExA(0, "MCIWndClass", NULL, wndStyle,
100 CW_USEDEFAULT, CW_USEDEFAULT,
101 CW_USEDEFAULT, CW_USEDEFAULT,
102 hwndParent, (HMENU)0, hInstance, mwi))
105 HeapFree(GetProcessHeap(), 0, mwi->lpName);
106 HeapFree(GetProcessHeap(), 0, mwi);
110 /***********************************************************************
111 * MCIWndCreateW [MSVFW32.@]
113 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
114 DWORD dwStyle, LPCWSTR szFile)
116 FIXME("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));
118 MCIWndRegisterClass(hInstance);
123 static DWORD MCIWND_GetStatus(MCIWndInfo* mwi)
125 MCI_DGV_STATUS_PARMSA mdsp;
127 memset(&mdsp, 0, sizeof(mdsp));
128 mdsp.dwItem = MCI_STATUS_MODE;
129 if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
130 return MCI_MODE_NOT_READY;
131 if (mdsp.dwReturn == MCI_MODE_STOP && mwi->uTimer) {
132 TRACE("Killing timer\n");
133 KillTimer(mwi->hWnd, 0);
136 return mdsp.dwReturn;
139 static DWORD MCIWND_Get(MCIWndInfo* mwi, DWORD what)
141 MCI_DGV_STATUS_PARMSA mdsp;
143 memset(&mdsp, 0, sizeof(mdsp));
145 if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
147 return mdsp.dwReturn;
150 static void MCIWND_SetText(MCIWndInfo* mwi)
154 if (mwi->dwStyle & MCIWNDF_SHOWNAME) {
155 strcpy(buffer, mwi->lpName);
160 if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
161 if (*buffer) strcat(buffer, " ");
165 if (mwi->dwStyle & MCIWNDF_SHOWPOS) {
166 sprintf(buffer + strlen(buffer), "%ld", MCIWND_Get(mwi, MCI_STATUS_POSITION));
169 if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
170 strcat(buffer, " - ");
173 if (mwi->dwStyle & MCIWNDF_SHOWMODE) {
174 switch (MCIWND_GetStatus(mwi)) {
175 case MCI_MODE_NOT_READY: strcat(buffer, "not ready"); break;
176 case MCI_MODE_PAUSE: strcat(buffer, "paused"); break;
177 case MCI_MODE_PLAY: strcat(buffer, "playing"); break;
178 case MCI_MODE_STOP: strcat(buffer, "stopped"); break;
179 case MCI_MODE_OPEN: strcat(buffer, "open"); break;
180 case MCI_MODE_RECORD: strcat(buffer, "recording"); break;
181 case MCI_MODE_SEEK: strcat(buffer, "seeking"); break;
182 default: strcat(buffer, "???"); break;
185 if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
186 strcat(buffer, " )");
188 TRACE("=> '%s'\n", buffer);
189 SetWindowTextA(mwi->hWnd, buffer);
192 static void MCIWND_Create(HWND hWnd, LPCREATESTRUCTA cs)
194 MCI_DGV_OPEN_PARMSA mdopn;
195 MCI_DGV_RECT_PARMS mdrct;
199 MCIWndInfo* mwi = (MCIWndInfo*)cs->lpCreateParams;
201 SetWindowLongA(hWnd, 0, (LPARAM)mwi);
204 /* now open MCI player for AVI file */
205 memset(&mdopn, 0, sizeof(mdopn));
206 mdopn.lpstrElementName = mwi->lpName;
207 mdopn.dwStyle = WS_VISIBLE|WS_CHILD;
208 mdopn.hWndParent = hWnd;
210 mmr = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS, (LPARAM)&mdopn);
212 MessageBoxA(GetTopWindow(hWnd), "Cannot open file", "MciWnd", MB_OK);
215 mwi->mci = mdopn.wDeviceID;
217 /* grab AVI window size */
218 memset(&mdrct, 0, sizeof(mdrct));
219 mmr = mciSendCommandA(mwi->mci, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (LPARAM)&mdrct);
221 WARN("Cannot get window rect\n");
224 cx = mdrct.rc.right - mdrct.rc.left;
225 cy = mdrct.rc.bottom - mdrct.rc.top;
227 AdjustWindowRect(&mdrct.rc, GetWindowLongA(hWnd, GWL_STYLE), FALSE);
228 SetWindowPos(hWnd, 0, 0, 0, mdrct.rc.right - mdrct.rc.left,
229 mdrct.rc.bottom - mdrct.rc.top + 32, SWP_NOMOVE|SWP_NOZORDER);
231 /* adding the other elements: play/stop button, menu button, status */
232 hChld = CreateWindowExA(0, "BUTTON", "Play", WS_CHILD|WS_VISIBLE, 0, cy, 32, 32,
233 hWnd, (HMENU)CTL_PLAYSTOP, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
234 TRACE("Get Button1: %04x\n", hChld);
235 hChld = CreateWindowExA(0, "BUTTON", "Menu", WS_CHILD|WS_VISIBLE, 32, cy, 32, 32,
236 hWnd, (HMENU)CTL_MENU, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
237 TRACE("Get Button2: %04x\n", hChld);
238 hChld = CreateWindowExA(0, TRACKBAR_CLASSA, "", WS_CHILD|WS_VISIBLE, 64, cy, cx - 64, 32,
239 hWnd, (HMENU)CTL_TRACKBAR, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
240 TRACE("Get status: %04x\n", hChld);
241 SendMessageA(hChld, TBM_SETRANGEMIN, 0L, 0L);
242 SendMessageA(hChld, TBM_SETRANGEMAX, 1L, MCIWND_Get(mwi, MCI_STATUS_LENGTH));
244 /* FIXME: no need to set it if child window */
248 static void MCIWND_Paint(MCIWndInfo* mwi, WPARAM wParam)
253 hdc = (wParam) ? (HDC)wParam : BeginPaint(mwi->hWnd, &ps);
254 /* something to do ? */
255 if (!wParam) EndPaint(mwi->hWnd, &ps);
258 static void MCIWND_ToggleState(MCIWndInfo* mwi)
260 MCI_GENERIC_PARMS mgp;
261 MCI_DGV_PLAY_PARMS mdply;
263 memset(&mgp, 0, sizeof(mgp));
264 memset(&mdply, 0, sizeof(mdply));
266 switch (MCIWND_GetStatus(mwi)) {
267 case MCI_MODE_NOT_READY:
268 case MCI_MODE_RECORD:
271 TRACE("Cannot do much...\n");
274 mciSendCommandA(mwi->mci, MCI_RESUME, MCI_WAIT, (LPARAM)&mgp);
277 mciSendCommandA(mwi->mci, MCI_PAUSE, MCI_WAIT, (LPARAM)&mgp);
281 mciSendCommandA(mwi->mci, MCI_PLAY, MCI_FROM, (LPARAM)&mdply);
282 mwi->uTimer = SetTimer(mwi->hWnd, 0, 333, 0L);
283 TRACE("Timer=%u\n", mwi->uTimer);
288 static LRESULT MCIWND_Command(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
290 switch (LOWORD(wParam)) {
291 case CTL_PLAYSTOP: MCIWND_ToggleState(mwi); break;
295 MessageBoxA(0, "ooch", "NIY", MB_OK);
300 static void MCIWND_Timer(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
302 TRACE("%ld\n", MCIWND_Get(mwi, MCI_STATUS_POSITION));
303 SendDlgItemMessageA(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, 1, MCIWND_Get(mwi, MCI_STATUS_POSITION));
307 static void MCIWND_Close(MCIWndInfo* mwi)
309 MCI_GENERIC_PARMS mgp;
311 memset(&mgp, 0, sizeof(mgp));
313 mciSendCommandA(mwi->mci, MCI_CLOSE, 0, (LPARAM)&mgp);
316 static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2)
318 MCIWndInfo* mwi = (MCIWndInfo*)GetWindowLongA(hWnd, 0);
320 if (mwi || wMsg == WM_CREATE) {
323 MCIWND_Create(hWnd, (CREATESTRUCTA*)lParam2);
327 HeapFree(GetProcessHeap(), 0, mwi->lpName);
328 HeapFree(GetProcessHeap(), 0, mwi);
331 MCIWND_Paint(mwi, lParam1);
334 return MCIWND_Command(mwi, lParam1, lParam2);
336 MCIWND_Timer(mwi, lParam1, lParam2);
341 return DefWindowProcA(hWnd, wMsg, lParam1, lParam2);