Commit 8c9ccf86 authored by Akihiro Sagawa's avatar Akihiro Sagawa Committed by Alexandre Julliard

mciqtz32: Correct video window behavior by creating default window.

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=52448Signed-off-by: 's avatarAkihiro Sagawa <sagawa.aki@gmail.com>
parent e0863109
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#include <math.h> #include <math.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
...@@ -31,6 +32,8 @@ ...@@ -31,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mciqtz); 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_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS);
static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS); static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
...@@ -68,6 +71,24 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID) ...@@ -68,6 +71,24 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID)
return wma; return wma;
} }
static void unregister_class(void)
{
UnregisterClassW(mciqtz_class, MCIQTZ_hInstance);
}
static bool register_class(void)
{
WNDCLASSW class = {0};
class.lpfnWndProc = DefWindowProcW;
class.cbWndExtra = sizeof(MCIDEVICEID);
class.hInstance = MCIQTZ_hInstance;
class.hCursor = LoadCursorW(0, (const WCHAR *)IDC_ARROW);
class.lpszClassName = mciqtz_class;
return RegisterClassW(&class) || GetLastError() == ERROR_CLASS_ALREADY_EXISTS;
}
/************************************************************************** /**************************************************************************
* MCIQTZ_drvOpen [internal] * MCIQTZ_drvOpen [internal]
*/ */
...@@ -81,6 +102,9 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp) ...@@ -81,6 +102,9 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
if (!modp) if (!modp)
return 0xFFFFFFFF; return 0xFFFFFFFF;
if (!register_class())
return 0;
wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIQTZ)); wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIQTZ));
if (!wma) if (!wma)
return 0; return 0;
...@@ -109,6 +133,7 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID) ...@@ -109,6 +133,7 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID)
/* finish all outstanding things */ /* finish all outstanding things */
MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL); MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL);
unregister_class();
mciFreeCommandResource(wma->command_table); mciFreeCommandResource(wma->command_table);
mciSetDriverData(dwDevID, 0); mciSetDriverData(dwDevID, 0);
CloseHandle(wma->stop_event); CloseHandle(wma->stop_event);
...@@ -139,6 +164,64 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID) ...@@ -139,6 +164,64 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID)
return 1; return 1;
} }
static bool create_window(WINE_MCIQTZ *wma, DWORD flags, const MCI_DGV_OPEN_PARMSW *params)
{
DWORD style = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) & ~WS_MAXIMIZEBOX;
LONG width, height, min_width;
HWND parent = NULL;
HRESULT hr;
RECT rc;
if (flags & MCI_DGV_OPEN_PARENT)
parent = params->hWndParent;
if (flags & MCI_DGV_OPEN_WS)
style = params->dwStyle;
hr = IBasicVideo_GetVideoSize(wma->vidbasic, &width, &height);
if (hr == E_NOINTERFACE)
return true; /* audio file */
else if (FAILED(hr))
{
ERR("Failed to get video size, hr %#lx.\n", hr);
return false;
}
/* Native always assumes an overlapped window
* when calculating default video window size. */
SetRect(&rc, 0, 0, width, height);
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
min_width = GetSystemMetrics(SM_CXMIN);
width = max(rc.right - rc.left, min_width);
height = rc.bottom - rc.top;
wma->window = CreateWindowW(mciqtz_class, params->lpstrElementName, style,
CW_USEDEFAULT, CW_USEDEFAULT, width, height, parent, NULL, MCIQTZ_hInstance, NULL);
TRACE("device %#x, flags %#lx, style %#lx, parent %p, dimensions %ldx%ld, created window %p.\n",
wma->wDevID, flags, style, parent, width, height, wma->window);
if (!wma->window)
{
ERR("Failed to create window, error %lu.\n", GetLastError());
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] * MCIQTZ_mciNotify [internal]
* *
...@@ -161,8 +244,6 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, ...@@ -161,8 +244,6 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags,
{ {
WINE_MCIQTZ* wma; WINE_MCIQTZ* wma;
HRESULT hr; HRESULT hr;
DWORD style = 0;
RECT rc = { 0, 0, 0, 0 };
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms); TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
...@@ -238,22 +319,8 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, ...@@ -238,22 +319,8 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags,
goto err; goto err;
} }
IVideoWindow_put_AutoShow(wma->vidwin, OAFALSE); if (!create_window(wma, dwFlags, lpOpenParms))
IVideoWindow_put_Visible(wma->vidwin, OAFALSE); goto err;
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;
}
else if (style)
IVideoWindow_put_WindowStyle(wma->vidwin, style);
IBasicVideo_GetVideoSize(wma->vidbasic, &rc.right, &rc.bottom);
wma->opened = TRUE; wma->opened = TRUE;
if (dwFlags & MCI_NOTIFY) if (dwFlags & MCI_NOTIFY)
...@@ -307,6 +374,13 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP ...@@ -307,6 +374,13 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP
MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL); MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL);
if (wma->opened) { 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); IVideoWindow_Release(wma->vidwin);
IBasicVideo_Release(wma->vidbasic); IBasicVideo_Release(wma->vidbasic);
IBasicAudio_Release(wma->audio); IBasicAudio_Release(wma->audio);
...@@ -447,7 +521,8 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms ...@@ -447,7 +521,8 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
return MCIERR_INTERNAL; return MCIERR_INTERNAL;
} }
IVideoWindow_put_Visible(wma->vidwin, OATRUE); if (wma->parent)
ShowWindow(wma->parent, SW_SHOW);
if (!wma->thread) if (!wma->thread)
{ {
...@@ -919,21 +994,11 @@ static DWORD MCIQTZ_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMS ...@@ -919,21 +994,11 @@ static DWORD MCIQTZ_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMS
return 0; return 0;
if (dwFlags & MCI_DGV_WINDOW_HWND && (IsWindow(lpParms->hWnd) || !lpParms->hWnd)) { if (dwFlags & MCI_DGV_WINDOW_HWND && (IsWindow(lpParms->hWnd) || !lpParms->hWnd)) {
LONG visible = OATRUE; HWND hwnd = lpParms->hWnd ? lpParms->hWnd : wma->window;
LONG style = 0; TRACE("Setting parent window to %p.\n", hwnd);
TRACE("Setting hWnd to %p\n", lpParms->hWnd); IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)hwnd);
IVideoWindow_get_Visible(wma->vidwin, &visible); IVideoWindow_put_Owner(wma->vidwin, (OAHWND)hwnd);
IVideoWindow_put_Visible(wma->vidwin, OAFALSE); wma->parent = hwnd;
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;
} }
if (dwFlags & MCI_DGV_WINDOW_STATE) { if (dwFlags & MCI_DGV_WINDOW_STATE) {
TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow); TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
......
...@@ -42,6 +42,7 @@ typedef struct { ...@@ -42,6 +42,7 @@ typedef struct {
REFERENCE_TIME seek_stop; REFERENCE_TIME seek_stop;
UINT command_table; UINT command_table;
HWND parent; HWND parent;
HWND window;
MCIDEVICEID notify_devid; MCIDEVICEID notify_devid;
HANDLE callback; HANDLE callback;
HANDLE thread; HANDLE thread;
......
...@@ -1566,15 +1566,10 @@ static void test_video_window(void) ...@@ -1566,15 +1566,10 @@ static void test_video_window(void)
{ {
video_window = NULL; video_window = NULL;
EnumWindows(my_visible_window_proc, (LPARAM)&video_window); 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");
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); hwnd = GetWindow(video_window, GW_OWNER);
todo_wine_if (testcase[i].open_flags & MCI_DGV_OPEN_PARENT) ok(hwnd == parent_window, "Got owner %p, expected %p.\n", hwnd, parent_window);
ok(hwnd == parent_window, "Got owner %p, expected %p.\n", hwnd, parent_window);
} }
else else
{ {
...@@ -1588,8 +1583,7 @@ static void test_video_window(void) ...@@ -1588,8 +1583,7 @@ static void test_video_window(void)
expected = testcase[i].expected_style | WS_VISIBLE; expected = testcase[i].expected_style | WS_VISIBLE;
style = GetWindowLongW(video_window, GWL_STYLE); style = GetWindowLongW(video_window, GWL_STYLE);
todo_wine_if (i != 3) ok(style == expected, "Got style %#lx for window %p, expected %#lx.\n", style, video_window, expected);
ok(style == expected, "Got style %#lx for window %p, expected %#lx.\n", style, video_window, expected);
/* Get the source video size. */ /* Get the source video size. */
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_SOURCE, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_SOURCE, (DWORD_PTR)&parm);
...@@ -1623,16 +1617,16 @@ static void test_video_window(void) ...@@ -1623,16 +1617,16 @@ static void test_video_window(void)
GetWindowRect(video_window, &win_rc); GetWindowRect(video_window, &win_rc);
OffsetRect(&rc, win_rc.left, win_rc.top); OffsetRect(&rc, win_rc.left, win_rc.top);
todo_wine_if (testcase[i].style & WS_CHILD) ok(EqualRect(&rc, &win_rc), "Got window rect %s, expected %s.\n",
ok(EqualRect(&rc, &win_rc), "Got window rect %s, expected %s.\n", wine_dbgstr_rect(&win_rc), wine_dbgstr_rect(&rc));
wine_dbgstr_rect(&win_rc), wine_dbgstr_rect(&rc));
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_WINDOW, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_WINDOW, (DWORD_PTR)&parm);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %s.\n", dbg_mcierr(err));
win_rc.right -= win_rc.left; win_rc.right -= win_rc.left;
win_rc.bottom -= win_rc.top; win_rc.bottom -= win_rc.top;
ok(EqualRect(&win_rc, &parm.where.rc), "Got rect %s, expected %s.\n", todo_wine_if (!(style & WS_CHILD))
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&win_rc)); ok(EqualRect(&win_rc, &parm.where.rc), "Got rect %s, expected %s.\n",
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&win_rc));
err = mciSendCommandW(id, MCI_STOP, 0, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_STOP, 0, (DWORD_PTR)&parm);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %s.\n", dbg_mcierr(err));
...@@ -1656,11 +1650,11 @@ static void test_video_window(void) ...@@ -1656,11 +1650,11 @@ static void test_video_window(void)
ok(!IsWindowVisible(main_window), "Main window should be hidden.\n"); ok(!IsWindowVisible(main_window), "Main window should be hidden.\n");
hwnd = GetWindow(main_window, GW_CHILD); hwnd = GetWindow(main_window, GW_CHILD);
todo_wine ok(hwnd != video_window, ok(hwnd != video_window, "Video window (%p) and child window (%p) should be different.\n",
"Video window (%p) and child window (%p) should be different.\n", video_window, hwnd); video_window, hwnd);
style = GetWindowLongW(hwnd, GWL_STYLE); style = GetWindowLongW(hwnd, GWL_STYLE);
expected = WS_CHILD | WS_VISIBLE; expected = WS_CHILD | WS_VISIBLE;
todo_wine ok(style == expected, "Child window %p: got style %#lx, expected %#lx.\n", ok(style == expected, "Child window %p: got style %#lx, expected %#lx.\n",
hwnd, style, expected); hwnd, style, expected);
style = GetWindowLongW(video_window, GWL_STYLE); style = GetWindowLongW(video_window, GWL_STYLE);
...@@ -1687,30 +1681,28 @@ static void test_video_window(void) ...@@ -1687,30 +1681,28 @@ static void test_video_window(void)
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %s.\n", dbg_mcierr(err));
todo_wine_if ((testcase[i].style & (WS_CHILD | WS_POPUP)) != WS_CHILD) ok(EqualRect(&parm.where.rc, &rc), "Got destination rect %s, expected %s.\n",
ok(EqualRect(&parm.where.rc, &rc), "Got destination rect %s, expected %s.\n", wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&rc));
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&rc));
/* MCI_PLAY shows current video window */ /* MCI_PLAY shows current video window */
err = mciSendCommandW(id, MCI_PLAY, 0, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_PLAY, 0, (DWORD_PTR)&parm);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %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(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 */ /* video window is reset to the default window, which is visible again */
parm.win.hWnd = NULL; parm.win.hWnd = NULL;
err = mciSendCommandW(id, MCI_WINDOW, MCI_DGV_WINDOW_HWND, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_WINDOW, MCI_DGV_WINDOW_HWND, (DWORD_PTR)&parm);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %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");
todo_wine ok(IsWindowVisible(video_window), "Video window should be shown.\n"); ok(IsWindowVisible(video_window), "Video window should be shown.\n");
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm); err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %s.\n", dbg_mcierr(err));
todo_wine ok(EqualRect(&parm.where.rc, &src_rc), "Got destination rect %s, expected %s.\n", todo_wine ok(EqualRect(&parm.where.rc, &src_rc), "Got destination rect %s, expected %s.\n",
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&src_rc)); wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&src_rc));
next:
err = mciSendCommandW(id, MCI_CLOSE, 0, 0); err = mciSendCommandW(id, MCI_CLOSE, 0, 0);
ok(!err, "Got %s.\n", dbg_mcierr(err)); ok(!err, "Got %s.\n", dbg_mcierr(err));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment