From: Akihiro Sagawa sagawa.aki@gmail.com
Now the video renderer window by IVideoWindow always has WS_CHILD style regardless open parameters.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52448 Signed-off-by: Akihiro Sagawa sagawa.aki@gmail.com --- dlls/mciqtz32/mciqtz.c | 125 ++++++++++++++++++++++++--------- dlls/mciqtz32/mciqtz_private.h | 1 + dlls/winmm/tests/mci.c | 21 ++---- 3 files changed, 101 insertions(+), 46 deletions(-)
diff --git a/dlls/mciqtz32/mciqtz.c b/dlls/mciqtz32/mciqtz.c index 05929d25680..3ce42bc9e18 100644 --- a/dlls/mciqtz32/mciqtz.c +++ b/dlls/mciqtz32/mciqtz.c @@ -31,6 +31,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mciqtz);
+static const WCHAR *MCIQTZ_CLASS = L"MCIQTZ_Window"; + static DWORD MCIQTZ_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS); static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
@@ -68,6 +70,28 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID) return wma; }
+static BOOL MCIQTZ_UnregisterClass(void) +{ + return UnregisterClassW(MCIQTZ_CLASS, MCIQTZ_hInstance); +} + +static BOOL MCIQTZ_RegisterClass(void) +{ + WNDCLASSW wndClass; + + ZeroMemory(&wndClass, sizeof(WNDCLASSW)); + wndClass.lpfnWndProc = DefWindowProcW; + wndClass.cbWndExtra = sizeof(MCIDEVICEID); + wndClass.hInstance = MCIQTZ_hInstance; + wndClass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW); + wndClass.lpszClassName = MCIQTZ_CLASS; + + if (RegisterClassW(&wndClass)) return TRUE; + if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE; + + return FALSE; +} + /************************************************************************** * MCIQTZ_drvOpen [internal] */ @@ -81,6 +105,8 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp) if (!modp) return 0xFFFFFFFF;
+ if (!MCIQTZ_RegisterClass()) return 0; + wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIQTZ)); if (!wma) return 0; @@ -109,6 +135,7 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID) /* finish all outstanding things */ MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL);
+ MCIQTZ_UnregisterClass(); mciFreeCommandResource(wma->command_table); mciSetDriverData(dwDevID, 0); CloseHandle(wma->stop_event); @@ -139,6 +166,55 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID) return 1; }
+static BOOL MCIQTZ_CreateWindow(WINE_MCIQTZ* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSW lpParms) +{ + HWND parent = NULL; + DWORD style = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) & ~WS_MAXIMIZEBOX; + LONG width, height; + RECT rc; + HRESULT hr; + + if (dwFlags & MCI_DGV_OPEN_PARENT) parent = lpParms->hWndParent; + if (dwFlags & MCI_DGV_OPEN_WS) style = lpParms->dwStyle; + + hr = IBasicVideo_GetVideoSize(wma->vidbasic, &width, &height); + if (hr == E_NOINTERFACE) + return TRUE; /* audio file */ + else if (FAILED(hr)) + return FALSE; + + /* FIXME: Use video size here */ + width = 640; + height = 480; + + wma->window = CreateWindowW(MCIQTZ_CLASS, lpParms->lpstrElementName, style, + CW_USEDEFAULT, CW_USEDEFAULT, + width, height, + parent, 0, MCIQTZ_hInstance, + 0); + + TRACE("(%04x, %08lX, %p, style %#lx, parent %p, dimensions %ldx%ld, window %p)\n", wma->wDevID, + dwFlags, lpParms, style, parent, width, height, wma->window); + + if (!wma->window) + return FALSE; + + IVideoWindow_put_AutoShow(wma->vidwin, OAFALSE); + IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)wma->window); + IVideoWindow_put_Owner(wma->vidwin, (OAHWND)wma->window); + IVideoWindow_put_WindowStyle(wma->vidwin, WS_CHILD); /* reset window style */ + + GetClientRect(wma->window, &rc); + width = rc.right; + height = rc.bottom; + + IVideoWindow_SetWindowPosition(wma->vidwin, 0, 0, width, height); + IVideoWindow_put_Visible(wma->vidwin, OATRUE); + wma->parent = wma->window; + + return TRUE; +} + /************************************************************************** * MCIQTZ_mciNotify [internal] * @@ -161,8 +237,6 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, { WINE_MCIQTZ* wma; HRESULT hr; - DWORD style = 0; - RECT rc = { 0, 0, 0, 0 };
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
@@ -238,22 +312,11 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, goto err; }
- IVideoWindow_put_AutoShow(wma->vidwin, OAFALSE); - IVideoWindow_put_Visible(wma->vidwin, OAFALSE); - if (dwFlags & MCI_DGV_OPEN_WS) - style = lpOpenParms->dwStyle; - if (dwFlags & MCI_DGV_OPEN_PARENT) { - IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)lpOpenParms->hWndParent); - IVideoWindow_put_WindowState(wma->vidwin, SW_HIDE); - IVideoWindow_put_WindowStyle(wma->vidwin, style|WS_CHILD); - IVideoWindow_put_Owner(wma->vidwin, (OAHWND)lpOpenParms->hWndParent); - GetClientRect(lpOpenParms->hWndParent, &rc); - IVideoWindow_SetWindowPosition(wma->vidwin, rc.left, rc.top, rc.right - rc.top, rc.bottom - rc.top); - wma->parent = (HWND)lpOpenParms->hWndParent; + if (!MCIQTZ_CreateWindow(wma, dwFlags, lpOpenParms)) + { + TRACE("Cannot create video window\n"); + goto err; } - else if (style) - IVideoWindow_put_WindowStyle(wma->vidwin, style); - IBasicVideo_GetVideoSize(wma->vidbasic, &rc.right, &rc.bottom); wma->opened = TRUE;
if (dwFlags & MCI_NOTIFY) @@ -307,6 +370,13 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL);
if (wma->opened) { + if (wma->window) + { + IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)NULL); + IVideoWindow_put_Owner(wma->vidwin, (OAHWND)NULL); + DestroyWindow(wma->window); + wma->window = NULL; + } IVideoWindow_Release(wma->vidwin); IBasicVideo_Release(wma->vidbasic); IBasicAudio_Release(wma->audio); @@ -447,7 +517,8 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms return MCIERR_INTERNAL; }
- IVideoWindow_put_Visible(wma->vidwin, OATRUE); + if (wma->parent) + ShowWindow(wma->parent, SW_SHOW);
if (!wma->thread) { @@ -919,21 +990,11 @@ static DWORD MCIQTZ_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMS return 0;
if (dwFlags & MCI_DGV_WINDOW_HWND && (IsWindow(lpParms->hWnd) || !lpParms->hWnd)) { - LONG visible = OATRUE; - LONG style = 0; + HWND hwnd = lpParms->hWnd ? lpParms->hWnd : wma->window; TRACE("Setting hWnd to %p\n", lpParms->hWnd); - IVideoWindow_get_Visible(wma->vidwin, &visible); - IVideoWindow_put_Visible(wma->vidwin, OAFALSE); - IVideoWindow_get_WindowStyle(wma->vidwin, &style); - style &= ~WS_CHILD; - if (lpParms->hWnd) - IVideoWindow_put_WindowStyle(wma->vidwin, style|WS_CHILD); - else - IVideoWindow_put_WindowStyle(wma->vidwin, style); - IVideoWindow_put_Owner(wma->vidwin, (OAHWND)lpParms->hWnd); - IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)lpParms->hWnd); - IVideoWindow_put_Visible(wma->vidwin, visible); - wma->parent = lpParms->hWnd; + IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)hwnd); + IVideoWindow_put_Owner(wma->vidwin, (OAHWND)hwnd); + wma->parent = hwnd; } if (dwFlags & MCI_DGV_WINDOW_STATE) { TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow); diff --git a/dlls/mciqtz32/mciqtz_private.h b/dlls/mciqtz32/mciqtz_private.h index aa6fad99326..9206a88b3fa 100644 --- a/dlls/mciqtz32/mciqtz_private.h +++ b/dlls/mciqtz32/mciqtz_private.h @@ -42,6 +42,7 @@ typedef struct { REFERENCE_TIME seek_stop; UINT command_table; HWND parent; + HWND window; MCIDEVICEID notify_devid; HANDLE callback; HANDLE thread; diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c index f75e8f962ee..ee79670a704 100644 --- a/dlls/winmm/tests/mci.c +++ b/dlls/winmm/tests/mci.c @@ -1555,14 +1555,9 @@ static void test_video_window(void) { video_window = NULL; EnumWindows(my_visible_window_proc, (LPARAM)&video_window); - todo_wine_if(testcase[i].open_flags & MCI_DGV_OPEN_PARENT) ok(video_window != NULL, "video window should be shown\n");
- /* FIXME: Remove once Wine is fixed */ - if (!video_window) goto next; - hwnd = GetWindow(video_window, GW_OWNER); - todo_wine_if(testcase[i].open_flags & MCI_DGV_OPEN_PARENT) ok(hwnd == parent_window, "expected owner %p, got %p\n", parent_window, hwnd); } else @@ -1577,7 +1572,6 @@ static void test_video_window(void)
expected = testcase[i].expected_style | WS_VISIBLE; style = GetWindowLongW(video_window, GWL_STYLE); - todo_wine_if(i != 3) ok(style == expected, "hwnd %p: got %#lx, expected %#lx\n", video_window, style, expected);
/* get source video size */ @@ -1609,6 +1603,7 @@ static void test_video_window(void) ok(!err,"mciCommand where window returned %s\n", dbg_mcierr(err)); win_rc.right -= win_rc.left; /* right is width in MCI rect */ win_rc.bottom -= win_rc.top; /* bottom is height in MCI rect */ + todo_wine_if(!(style & WS_CHILD)) ok(EqualRect(&win_rc, &parm.where.rc), "window command result doesn't match, expected %s, got %s\n", wine_dbgstr_rect(&win_rc), wine_dbgstr_rect(&parm.where.rc));
err = mciSendCommandW(wDeviceID, MCI_STOP, 0, (DWORD_PTR)&parm); @@ -1633,10 +1628,10 @@ static void test_video_window(void) ok(!IsWindowVisible(main_window), "at this point, main window should be hidden\n");
hwnd = GetWindow(main_window, GW_CHILD); - todo_wine ok(hwnd != video_window, "video window (%p) and child window (%p) should have different handle values\n", video_window, hwnd); + ok(hwnd != video_window, "video window (%p) and child window (%p) should have different handle values\n", video_window, hwnd); style = GetWindowLongW(hwnd, GWL_STYLE); expected = WS_CHILD | WS_VISIBLE; - todo_wine ok(style == expected, "child hwnd %p: expected %#lx, got %#lx\n", hwnd, expected, style); + ok(style == expected, "child hwnd %p: expected %#lx, got %#lx\n", hwnd, expected, style);
style = GetWindowLongW(video_window, GWL_STYLE); expected = testcase[i].expected_style; @@ -1660,28 +1655,26 @@ static void test_video_window(void)
err = mciSendCommandW(wDeviceID, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm); ok(!err,"mciCommand where destination returned %s\n", dbg_mcierr(err)); - todo_wine_if((testcase[i].style & (WS_CHILD|WS_POPUP)) != WS_CHILD) ok(EqualRect(&parm.where.rc, &rc), "got %s, expected %s\n", wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&rc));
/* MCI_PLAY shows current video window */ err = mciSendCommandW(wDeviceID, MCI_PLAY, 0, (DWORD_PTR)&parm); ok(!err,"mciCommand play returned %s\n", dbg_mcierr(err)); - todo_wine ok(IsWindowVisible(main_window), "main window should be shown\n"); + ok(IsWindowVisible(main_window), "main window should be shown\n"); ok(IsWindow(video_window), "video window should exist\n"); - ok(!IsWindowVisible(video_window), "video window should be hidden\n"); + todo_wine ok(!IsWindowVisible(video_window), "video window should be hidden\n");
/* video window is reset to the default window, which is visible again */ parm.win.hWnd = NULL; err = mciSendCommandW(wDeviceID, MCI_WINDOW, MCI_DGV_WINDOW_HWND, (DWORD_PTR)&parm); ok(!err,"mciCommand window handle returned %s\n", dbg_mcierr(err)); - todo_wine ok(IsWindowVisible(main_window), "main window should be shown\n"); - todo_wine ok(IsWindowVisible(video_window), "video window should be shown, again\n"); + ok(IsWindowVisible(main_window), "main window should be shown\n"); + ok(IsWindowVisible(video_window), "video window should be shown, again\n");
err = mciSendCommandW(wDeviceID, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm); ok(!err,"mciCommand where destination returned %s\n", dbg_mcierr(err)); todo_wine ok(EqualRect(&parm.where.rc, &src_rc), "got %s, expected %s\n", wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&src_rc));
- next: err = mciSendCommandW(wDeviceID, MCI_CLOSE, 0, 0); ok(!err,"mciCommand close returned %s\n", dbg_mcierr(err));