Documentation fixes.
[wine] / dlls / msvideo / mciwnd.c
1 /*
2  * Copyright 2000 Eric Pouech 
3  *
4  */
5
6 #include <stdio.h>
7 #include <string.h>
8
9 #include "winbase.h"
10 #include "windef.h"
11 #include "winnls.h"
12 #include "wingdi.h"
13 #include "winuser.h"
14 #include "vfw.h"
15 #include "wine/mmsystem16.h"
16 #include "digitalv.h"
17 #include "commctrl.h"
18 #include "debugtools.h"
19
20 DEFAULT_DEBUG_CHANNEL(mci);
21
22 typedef struct {
23    DWORD        dwStyle;
24    MCIDEVICEID  mci;
25    LPSTR        lpName;
26    HWND         hWnd;
27    UINT         uTimer;
28 } MCIWndInfo;
29
30 static LRESULT WINAPI   MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2);
31
32 #define CTL_PLAYSTOP    0x3200
33 #define CTL_MENU        0x3201
34 #define CTL_TRACKBAR    0x3202
35
36 /***********************************************************************
37  *              MCIWndRegisterClass             [MSVFW32.@]
38  */
39 BOOL WINAPI MCIWndRegisterClass(HINSTANCE hInst)
40 {
41    WNDCLASSA            wc;
42
43    /* since window creation will also require some common controls, init them */
44    InitCommonControls();
45
46    wc.style = 0;
47    wc.lpfnWndProc = MCIWndProc;
48    wc.cbClsExtra = 0;
49    wc.cbWndExtra = sizeof(MCIWndInfo*);
50    wc.hInstance = hInst;
51    wc.hIcon = 0;
52    wc.hCursor = 0;
53    wc.hbrBackground = 0;
54    wc.lpszMenuName = NULL;
55    wc.lpszClassName = "MCIWndClass";
56
57    return RegisterClassA(&wc);
58
59 }
60
61 /***********************************************************************
62  *              MCIWndCreate            [MSVFW32.@]
63  *              MCIWndCreateA           [MSVFW32.@]
64  */
65 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
66                            DWORD dwStyle, LPCSTR szFile)
67 {
68    DWORD        wndStyle;
69    MCIWndInfo*  mwi;
70    
71    TRACE("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, szFile);
72
73    MCIWndRegisterClass(hInstance);
74
75    mwi = HeapAlloc(GetProcessHeap(), 0, sizeof(*mwi));
76    if (!mwi) return 0;
77
78    mwi->dwStyle = dwStyle;
79    mwi->lpName = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(szFile) + 1), szFile);
80    mwi->uTimer = 0;
81
82    wndStyle = ((hwndParent) ? (WS_CHILD|WS_BORDER) : WS_OVERLAPPEDWINDOW) |
83               WS_VISIBLE | (dwStyle & 0xFFFF0000);
84
85    if (CreateWindowExA(0, "MCIWndClass", NULL, wndStyle, 
86                        CW_USEDEFAULT, CW_USEDEFAULT, 
87                        CW_USEDEFAULT, CW_USEDEFAULT, 
88                        hwndParent, (HMENU)0, hInstance, mwi))
89       return mwi->hWnd;
90    
91    HeapFree(GetProcessHeap(), 0, mwi->lpName);
92    HeapFree(GetProcessHeap(), 0, mwi);
93    return 0;
94 }
95
96 /***********************************************************************
97  *              MCIWndCreateW                           [MSVFW32.@]
98  */
99 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
100                            DWORD dwStyle, LPCWSTR szFile)
101 {
102    FIXME("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));
103
104    MCIWndRegisterClass(hInstance);
105
106    return 0;
107 }
108
109 static DWORD MCIWND_GetStatus(MCIWndInfo* mwi)
110 {
111    MCI_DGV_STATUS_PARMSA        mdsp;
112    
113    memset(&mdsp, 0, sizeof(mdsp));
114    mdsp.dwItem = MCI_STATUS_MODE;
115    if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
116       return MCI_MODE_NOT_READY;
117    if (mdsp.dwReturn == MCI_MODE_STOP && mwi->uTimer) {
118       TRACE("Killing timer\n");
119       KillTimer(mwi->hWnd, 0);
120       mwi->uTimer = 0;
121    }
122    return mdsp.dwReturn;
123 }
124
125 static DWORD MCIWND_Get(MCIWndInfo* mwi, DWORD what)
126 {
127    MCI_DGV_STATUS_PARMSA        mdsp;
128       
129    memset(&mdsp, 0, sizeof(mdsp));
130    mdsp.dwItem = what;
131    if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
132       return 0;
133    return mdsp.dwReturn;
134 }
135
136 static void MCIWND_SetText(MCIWndInfo* mwi)
137 {
138    char buffer[1024];
139
140    if (mwi->dwStyle & MCIWNDF_SHOWNAME) {
141       strcpy(buffer, mwi->lpName);
142    } else {
143       *buffer = 0;
144    }
145
146    if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
147       if (*buffer) strcat(buffer, " ");
148       strcat(buffer, "(");
149    }
150
151    if (mwi->dwStyle & MCIWNDF_SHOWPOS) {
152       sprintf(buffer + strlen(buffer), "%ld", MCIWND_Get(mwi, MCI_STATUS_POSITION));
153    }
154
155    if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
156       strcat(buffer, " - ");
157    }
158
159    if (mwi->dwStyle & MCIWNDF_SHOWMODE) {
160       switch (MCIWND_GetStatus(mwi)) {
161       case MCI_MODE_NOT_READY:  strcat(buffer, "not ready");    break;
162       case MCI_MODE_PAUSE:      strcat(buffer, "paused");       break;
163       case MCI_MODE_PLAY:       strcat(buffer, "playing");      break;
164       case MCI_MODE_STOP:       strcat(buffer, "stopped");      break;
165       case MCI_MODE_OPEN:       strcat(buffer, "open");         break;
166       case MCI_MODE_RECORD:     strcat(buffer, "recording");    break;
167       case MCI_MODE_SEEK:       strcat(buffer, "seeking");      break;
168       default:                  strcat(buffer, "???");          break;
169       }
170    }
171    if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
172       strcat(buffer, " )");
173    }
174    TRACE("=> '%s'\n", buffer);
175    SetWindowTextA(mwi->hWnd, buffer);
176 }
177
178 static void MCIWND_Create(HWND hWnd, LPCREATESTRUCTA cs)
179 {
180    MCI_DGV_OPEN_PARMSA  mdopn;
181    MCI_DGV_RECT_PARMS   mdrct;
182    MMRESULT             mmr;
183    int                  cx, cy;
184    HWND                 hChld;
185    MCIWndInfo*          mwi = (MCIWndInfo*)cs->lpCreateParams;
186
187    SetWindowLongA(hWnd, 0, (LPARAM)mwi);
188    mwi->hWnd = hWnd;
189
190    /* now open MCI player for AVI file */
191    memset(&mdopn, 0, sizeof(mdopn));
192    mdopn.lpstrElementName = mwi->lpName;
193    mdopn.dwStyle = WS_VISIBLE|WS_CHILD;
194    mdopn.hWndParent = hWnd;
195
196    mmr = mciSendCommandA(0,  MCI_OPEN, MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS, (LPARAM)&mdopn);
197    if (mmr) {
198       MessageBoxA(GetTopWindow(hWnd), "Cannot open file", "MciWnd", MB_OK);
199       return;
200    }
201    mwi->mci = mdopn.wDeviceID;
202   
203    /* grab AVI window size */
204    memset(&mdrct, 0, sizeof(mdrct));
205    mmr = mciSendCommandA(mwi->mci,  MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (LPARAM)&mdrct);
206    if (mmr) {
207       WARN("Cannot get window rect\n");
208       return;
209    }
210    cx = mdrct.rc.right - mdrct.rc.left;
211    cy = mdrct.rc.bottom - mdrct.rc.top;
212
213    AdjustWindowRect(&mdrct.rc, GetWindowLongA(hWnd, GWL_STYLE), FALSE);
214    SetWindowPos(hWnd, 0, 0, 0, mdrct.rc.right - mdrct.rc.left, 
215                 mdrct.rc.bottom - mdrct.rc.top + 32, SWP_NOMOVE|SWP_NOZORDER);
216
217    /* adding the other elements: play/stop button, menu button, status */
218    hChld = CreateWindowExA(0, "BUTTON", "Play", WS_CHILD|WS_VISIBLE, 0, cy, 32, 32, 
219                            hWnd, (HMENU)CTL_PLAYSTOP, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
220    TRACE("Get Button1: %04x\n", hChld);
221    hChld = CreateWindowExA(0, "BUTTON", "Menu", WS_CHILD|WS_VISIBLE, 32, cy, 32, 32, 
222                            hWnd, (HMENU)CTL_MENU, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
223    TRACE("Get Button2: %04x\n", hChld);
224    hChld = CreateWindowExA(0, TRACKBAR_CLASSA, "", WS_CHILD|WS_VISIBLE, 64, cy, cx - 64, 32, 
225                            hWnd, (HMENU)CTL_TRACKBAR, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
226    TRACE("Get status: %04x\n", hChld);
227    SendMessageA(hChld, TBM_SETRANGEMIN, 0L, 0L);
228    SendMessageA(hChld, TBM_SETRANGEMAX, 1L, MCIWND_Get(mwi, MCI_STATUS_LENGTH));
229
230    /* FIXME: no need to set it if child window */
231    MCIWND_SetText(mwi);
232 }
233
234 static void MCIWND_Paint(MCIWndInfo* mwi, WPARAM wParam)
235 {
236    HDC          hdc;
237    PAINTSTRUCT  ps;
238
239    hdc = (wParam) ? (HDC)wParam : BeginPaint(mwi->hWnd, &ps);
240    /* something to do ? */
241    if (!wParam) EndPaint(mwi->hWnd, &ps);
242 }
243
244 static void MCIWND_ToggleState(MCIWndInfo* mwi)
245 {
246    MCI_GENERIC_PARMS    mgp;
247    MCI_DGV_PLAY_PARMS   mdply;
248
249    memset(&mgp, 0, sizeof(mgp));
250    memset(&mdply, 0, sizeof(mdply));
251
252    switch (MCIWND_GetStatus(mwi)) {
253    case MCI_MODE_NOT_READY:
254    case MCI_MODE_RECORD:
255    case MCI_MODE_SEEK:
256    case MCI_MODE_OPEN:
257       TRACE("Cannot do much...\n");
258       break;
259    case MCI_MODE_PAUSE:
260       mciSendCommandA(mwi->mci, MCI_RESUME, MCI_WAIT, (LPARAM)&mgp);
261       break;
262    case MCI_MODE_PLAY:
263       mciSendCommandA(mwi->mci, MCI_PAUSE, MCI_WAIT, (LPARAM)&mgp);
264       break;
265    case MCI_MODE_STOP:
266       mdply.dwFrom = 0L;
267       mciSendCommandA(mwi->mci, MCI_PLAY, MCI_FROM, (LPARAM)&mdply);
268       mwi->uTimer = SetTimer(mwi->hWnd, 0, 333, 0L);
269       TRACE("Timer=%u\n", mwi->uTimer);
270       break;
271    }
272 }
273
274 static LRESULT MCIWND_Command(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
275 {
276    switch (LOWORD(wParam)) {
277    case CTL_PLAYSTOP:   MCIWND_ToggleState(mwi);        break;
278    case CTL_MENU:
279    case CTL_TRACKBAR:
280    default:
281       MessageBoxA(0, "ooch", "NIY", MB_OK);
282    }
283    return 0L;
284 }
285
286 static void MCIWND_Timer(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
287 {
288    TRACE("%ld\n", MCIWND_Get(mwi, MCI_STATUS_POSITION));
289    SendDlgItemMessageA(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, 1, MCIWND_Get(mwi, MCI_STATUS_POSITION));
290    MCIWND_SetText(mwi);
291 }
292
293 static void MCIWND_Close(MCIWndInfo* mwi)
294 {
295    MCI_GENERIC_PARMS    mgp;
296
297    memset(&mgp, 0, sizeof(mgp));
298
299    mciSendCommandA(mwi->mci, MCI_CLOSE, 0, (LPARAM)&mgp);
300 }
301
302 static LRESULT WINAPI   MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2)
303 {
304    MCIWndInfo*  mwi = (MCIWndInfo*)GetWindowLongA(hWnd, 0);
305
306    if (mwi || wMsg == WM_CREATE) {
307       switch (wMsg) {
308       case WM_CREATE:
309          MCIWND_Create(hWnd, (CREATESTRUCTA*)lParam2);
310          return 0;
311       case WM_DESTROY:
312          MCIWND_Close(mwi);
313          HeapFree(GetProcessHeap(), 0, mwi->lpName);
314          HeapFree(GetProcessHeap(), 0, mwi);
315          break;
316       case WM_PAINT:
317          MCIWND_Paint(mwi, lParam1);
318          break;
319       case WM_COMMAND:
320          return MCIWND_Command(mwi, lParam1, lParam2);
321       case WM_TIMER:
322          MCIWND_Timer(mwi, lParam1, lParam2);
323          return TRUE;
324       }
325    }
326
327    return DefWindowProcA(hWnd, wMsg, lParam1, lParam2);
328 }
329