diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 5eb87fd8a02..60c063efbe3 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -447,7 +447,7 @@ mpr/libmpr.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@ msacm/libmsacm32.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libadvapi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ msnet32/libmsnet32.@LIBEXT@: libntdll.@LIBEXT@ msvcrt/libmsvcrt.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@ -msvideo/libmsvfw32.@LIBEXT@: libwinmm.@LIBEXT@ libversion.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ +msvideo/libmsvfw32.@LIBEXT@: libwinmm.@LIBEXT@ libcomctl32.@LIBEXT@ libversion.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ odbc32/libodbc32.@LIBEXT@: libntdll.@LIBEXT@ ole32/libole32.@LIBEXT@: libadvapi32.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ librpcrt4.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ oleaut32/liboleaut32.@LIBEXT@: libole32.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libadvapi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ diff --git a/dlls/msvideo/Makefile.in b/dlls/msvideo/Makefile.in index 988f8fb7e50..136a47a4a47 100644 --- a/dlls/msvideo/Makefile.in +++ b/dlls/msvideo/Makefile.in @@ -9,6 +9,7 @@ LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ + mciwnd.c \ msvideo_main.c \ drawdib.c diff --git a/dlls/msvideo/mciwnd.c b/dlls/msvideo/mciwnd.c new file mode 100644 index 00000000000..71e951003ab --- /dev/null +++ b/dlls/msvideo/mciwnd.c @@ -0,0 +1,329 @@ +/* + * Copyright 2000 Eric Pouech + * + */ + +#include +#include + +#include "winbase.h" +#include "windef.h" +#include "winnls.h" +#include "wingdi.h" +#include "winuser.h" +#include "vfw.h" +#include "wine/mmsystem16.h" +#include "digitalv.h" +#include "commctrl.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(mci); + +typedef struct { + DWORD dwStyle; + MCIDEVICEID mci; + LPSTR lpName; + HWND hWnd; + UINT uTimer; +} MCIWndInfo; + +static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2); + +#define CTL_PLAYSTOP 0x3200 +#define CTL_MENU 0x3201 +#define CTL_TRACKBAR 0x3202 + +/*********************************************************************** + * MCIWndRegisterClass [MSVFW.@] + */ +BOOL WINAPI MCIWndRegisterClass(HINSTANCE hInst) +{ + WNDCLASSA wc; + + /* since window creation will also require some common controls, init them */ + InitCommonControls(); + + wc.style = 0; + wc.lpfnWndProc = MCIWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(MCIWndInfo*); + wc.hInstance = hInst; + wc.hIcon = 0; + wc.hCursor = 0; + wc.hbrBackground = 0; + wc.lpszMenuName = NULL; + wc.lpszClassName = "MCIWndClass"; + + return RegisterClassA(&wc); + +} + +/*********************************************************************** + * MCIWndCreate [MSVFW.@] + * MCIWndCreateA [MSVFW.@] + */ +HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance, + DWORD dwStyle, LPCSTR szFile) +{ + DWORD wndStyle; + MCIWndInfo* mwi; + + TRACE("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, szFile); + + MCIWndRegisterClass(hInstance); + + mwi = HeapAlloc(GetProcessHeap(), 0, sizeof(*mwi)); + if (!mwi) return 0; + + mwi->dwStyle = dwStyle; + mwi->lpName = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(szFile) + 1), szFile); + mwi->uTimer = 0; + + wndStyle = ((hwndParent) ? (WS_CHILD|WS_BORDER) : WS_OVERLAPPEDWINDOW) | + WS_VISIBLE | (dwStyle & 0xFFFF0000); + + if (CreateWindowExA(0, "MCIWndClass", NULL, wndStyle, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hwndParent, (HMENU)0, hInstance, mwi)) + return mwi->hWnd; + + HeapFree(GetProcessHeap(), 0, mwi->lpName); + HeapFree(GetProcessHeap(), 0, mwi); + return 0; +} + +/*********************************************************************** + * MCIWndCreateW [MSVFW.@] + */ +HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, + DWORD dwStyle, LPCWSTR szFile) +{ + FIXME("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile)); + + MCIWndRegisterClass(hInstance); + + return 0; +} + +static DWORD MCIWND_GetStatus(MCIWndInfo* mwi) +{ + MCI_DGV_STATUS_PARMSA mdsp; + + memset(&mdsp, 0, sizeof(mdsp)); + mdsp.dwItem = MCI_STATUS_MODE; + if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp)) + return MCI_MODE_NOT_READY; + if (mdsp.dwReturn == MCI_MODE_STOP && mwi->uTimer) { + TRACE("Killing timer\n"); + KillTimer(mwi->hWnd, 0); + mwi->uTimer = 0; + } + return mdsp.dwReturn; +} + +static DWORD MCIWND_Get(MCIWndInfo* mwi, DWORD what) +{ + MCI_DGV_STATUS_PARMSA mdsp; + + memset(&mdsp, 0, sizeof(mdsp)); + mdsp.dwItem = what; + if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp)) + return 0; + return mdsp.dwReturn; +} + +static void MCIWND_SetText(MCIWndInfo* mwi) +{ + char buffer[1024]; + + if (mwi->dwStyle & MCIWNDF_SHOWNAME) { + strcpy(buffer, mwi->lpName); + } else { + *buffer = 0; + } + + if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) { + if (*buffer) strcat(buffer, " "); + strcat(buffer, "("); + } + + if (mwi->dwStyle & MCIWNDF_SHOWPOS) { + sprintf(buffer + strlen(buffer), "%ld", MCIWND_Get(mwi, MCI_STATUS_POSITION)); + } + + if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) { + strcat(buffer, " - "); + } + + if (mwi->dwStyle & MCIWNDF_SHOWMODE) { + switch (MCIWND_GetStatus(mwi)) { + case MCI_MODE_NOT_READY: strcat(buffer, "not ready"); break; + case MCI_MODE_PAUSE: strcat(buffer, "paused"); break; + case MCI_MODE_PLAY: strcat(buffer, "playing"); break; + case MCI_MODE_STOP: strcat(buffer, "stopped"); break; + case MCI_MODE_OPEN: strcat(buffer, "open"); break; + case MCI_MODE_RECORD: strcat(buffer, "recording"); break; + case MCI_MODE_SEEK: strcat(buffer, "seeking"); break; + default: strcat(buffer, "???"); break; + } + } + if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) { + strcat(buffer, " )"); + } + TRACE("=> '%s'\n", buffer); + SetWindowTextA(mwi->hWnd, buffer); +} + +static void MCIWND_Create(HWND hWnd, LPCREATESTRUCTA cs) +{ + MCI_DGV_OPEN_PARMSA mdopn; + MCI_DGV_RECT_PARMS mdrct; + MMRESULT mmr; + int cx, cy; + HWND hChld; + MCIWndInfo* mwi = (MCIWndInfo*)cs->lpCreateParams; + + SetWindowLongA(hWnd, 0, (LPARAM)mwi); + mwi->hWnd = hWnd; + + /* now open MCI player for AVI file */ + memset(&mdopn, 0, sizeof(mdopn)); + mdopn.lpstrElementName = mwi->lpName; + mdopn.dwStyle = WS_VISIBLE|WS_CHILD; + mdopn.hWndParent = hWnd; + + mmr = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS, (LPARAM)&mdopn); + if (mmr) { + MessageBoxA(GetTopWindow(hWnd), "Cannot open file", "MciWnd", MB_OK); + return; + } + mwi->mci = mdopn.wDeviceID; + + /* grab AVI window size */ + memset(&mdrct, 0, sizeof(mdrct)); + mmr = mciSendCommandA(mwi->mci, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (LPARAM)&mdrct); + if (mmr) { + WARN("Cannot get window rect\n"); + return; + } + cx = mdrct.rc.right - mdrct.rc.left; + cy = mdrct.rc.bottom - mdrct.rc.top; + + AdjustWindowRect(&mdrct.rc, GetWindowLongA(hWnd, GWL_STYLE), FALSE); + SetWindowPos(hWnd, 0, 0, 0, mdrct.rc.right - mdrct.rc.left, + mdrct.rc.bottom - mdrct.rc.top + 32, SWP_NOMOVE|SWP_NOZORDER); + + /* adding the other elements: play/stop button, menu button, status */ + hChld = CreateWindowExA(0, "BUTTON", "Play", WS_CHILD|WS_VISIBLE, 0, cy, 32, 32, + hWnd, (HMENU)CTL_PLAYSTOP, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L); + TRACE("Get Button1: %04x\n", hChld); + hChld = CreateWindowExA(0, "BUTTON", "Menu", WS_CHILD|WS_VISIBLE, 32, cy, 32, 32, + hWnd, (HMENU)CTL_MENU, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L); + TRACE("Get Button2: %04x\n", hChld); + hChld = CreateWindowExA(0, TRACKBAR_CLASSA, "", WS_CHILD|WS_VISIBLE, 64, cy, cx - 64, 32, + hWnd, (HMENU)CTL_TRACKBAR, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L); + TRACE("Get status: %04x\n", hChld); + SendMessageA(hChld, TBM_SETRANGEMIN, 0L, 0L); + SendMessageA(hChld, TBM_SETRANGEMAX, 1L, MCIWND_Get(mwi, MCI_STATUS_LENGTH)); + + /* FIXME: no need to set it if child window */ + MCIWND_SetText(mwi); +} + +static void MCIWND_Paint(MCIWndInfo* mwi, WPARAM wParam) +{ + HDC hdc; + PAINTSTRUCT ps; + + hdc = (wParam) ? (HDC)wParam : BeginPaint(mwi->hWnd, &ps); + /* something to do ? */ + if (!wParam) EndPaint(mwi->hWnd, &ps); +} + +static void MCIWND_ToggleState(MCIWndInfo* mwi) +{ + MCI_GENERIC_PARMS mgp; + MCI_DGV_PLAY_PARMS mdply; + + memset(&mgp, 0, sizeof(mgp)); + memset(&mdply, 0, sizeof(mdply)); + + switch (MCIWND_GetStatus(mwi)) { + case MCI_MODE_NOT_READY: + case MCI_MODE_RECORD: + case MCI_MODE_SEEK: + case MCI_MODE_OPEN: + TRACE("Cannot do much...\n"); + break; + case MCI_MODE_PAUSE: + mciSendCommandA(mwi->mci, MCI_RESUME, MCI_WAIT, (LPARAM)&mgp); + break; + case MCI_MODE_PLAY: + mciSendCommandA(mwi->mci, MCI_PAUSE, MCI_WAIT, (LPARAM)&mgp); + break; + case MCI_MODE_STOP: + mdply.dwFrom = 0L; + mciSendCommandA(mwi->mci, MCI_PLAY, MCI_FROM, (LPARAM)&mdply); + mwi->uTimer = SetTimer(mwi->hWnd, 0, 333, 0L); + TRACE("Timer=%u\n", mwi->uTimer); + break; + } +} + +static LRESULT MCIWND_Command(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam) +{ + switch (LOWORD(wParam)) { + case CTL_PLAYSTOP: MCIWND_ToggleState(mwi); break; + case CTL_MENU: + case CTL_TRACKBAR: + default: + MessageBoxA(0, "ooch", "NIY", MB_OK); + } + return 0L; +} + +static void MCIWND_Timer(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam) +{ + TRACE("%ld\n", MCIWND_Get(mwi, MCI_STATUS_POSITION)); + SendDlgItemMessageA(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, 1, MCIWND_Get(mwi, MCI_STATUS_POSITION)); + MCIWND_SetText(mwi); +} + +static void MCIWND_Close(MCIWndInfo* mwi) +{ + MCI_GENERIC_PARMS mgp; + + memset(&mgp, 0, sizeof(mgp)); + + mciSendCommandA(mwi->mci, MCI_CLOSE, 0, (LPARAM)&mgp); +} + +static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2) +{ + MCIWndInfo* mwi = (MCIWndInfo*)GetWindowLongA(hWnd, 0); + + if (mwi || wMsg == WM_CREATE) { + switch (wMsg) { + case WM_CREATE: + MCIWND_Create(hWnd, (CREATESTRUCTA*)lParam2); + return 0; + case WM_DESTROY: + MCIWND_Close(mwi); + HeapFree(GetProcessHeap(), 0, mwi->lpName); + HeapFree(GetProcessHeap(), 0, mwi); + break; + case WM_PAINT: + MCIWND_Paint(mwi, lParam1); + break; + case WM_COMMAND: + return MCIWND_Command(mwi, lParam1, lParam2); + case WM_TIMER: + MCIWND_Timer(mwi, lParam1, lParam2); + return TRUE; + } + } + + return DefWindowProcA(hWnd, wMsg, lParam1, lParam2); +} + diff --git a/dlls/msvideo/msvfw32.spec b/dlls/msvideo/msvfw32.spec index b23e8290095..93e20a7ca10 100644 --- a/dlls/msvideo/msvfw32.spec +++ b/dlls/msvideo/msvfw32.spec @@ -2,13 +2,14 @@ name msvfw32 type win32 import winmm.dll +import comctl32.dll import version.dll import user32.dll import gdi32.dll import kernel32.dll import ntdll.dll -debug_channels (msvideo) +debug_channels (mci msvideo) # Yes, ICCompress,ICDecompress,MCIWnd* and ICDraw* are cdecl (VFWAPIV). # The rest is stdcall (VFWAPI) however. -Marcus Meissner, 990124 @@ -59,5 +60,5 @@ debug_channels (msvideo) @ cdecl MCIWndCreate (long long long str) MCIWndCreateA @ cdecl MCIWndCreateA (long long long str) MCIWndCreateA @ cdecl MCIWndCreateW (long long long wstr) MCIWndCreateW -@ stub MCIWndRegisterClass +@ stdcall MCIWndRegisterClass (long) MCIWndRegisterClass @ stub StretchDIB diff --git a/dlls/msvideo/msvideo_main.c b/dlls/msvideo/msvideo_main.c index f97f2984656..5cd6bb31baf 100644 --- a/dlls/msvideo/msvideo_main.c +++ b/dlls/msvideo/msvideo_main.c @@ -1182,23 +1182,3 @@ LRESULT WINAPI ICClose16(HIC16 hic) { return ICClose(hic); } -/*********************************************************************** - * MCIWndCreate [MSVFW32.@] - * MCIWndCreateA [MSVFW32.@] - */ -HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance, - DWORD dwStyle,LPCSTR szFile) -{ - FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile); - return 0; -} - -/*********************************************************************** - * MCIWndCreateW [MSVFW32.@] - */ -HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, - DWORD dwStyle,LPCWSTR szFile) -{ - FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile)); - return 0; -}