mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:50:49 +00:00
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=52448 Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com>
This commit is contained in:
parent
e08631097e
commit
8c9ccf8622
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -31,6 +32,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 +71,24 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID)
|
|||
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]
|
||||
*/
|
||||
|
@ -81,6 +102,9 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
|
|||
if (!modp)
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
if (!register_class())
|
||||
return 0;
|
||||
|
||||
wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIQTZ));
|
||||
if (!wma)
|
||||
return 0;
|
||||
|
@ -109,6 +133,7 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID)
|
|||
/* finish all outstanding things */
|
||||
MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL);
|
||||
|
||||
unregister_class();
|
||||
mciFreeCommandResource(wma->command_table);
|
||||
mciSetDriverData(dwDevID, 0);
|
||||
CloseHandle(wma->stop_event);
|
||||
|
@ -139,6 +164,64 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID)
|
|||
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]
|
||||
*
|
||||
|
@ -161,8 +244,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 +319,8 @@ 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;
|
||||
}
|
||||
else if (style)
|
||||
IVideoWindow_put_WindowStyle(wma->vidwin, style);
|
||||
IBasicVideo_GetVideoSize(wma->vidbasic, &rc.right, &rc.bottom);
|
||||
if (!create_window(wma, dwFlags, lpOpenParms))
|
||||
goto err;
|
||||
wma->opened = TRUE;
|
||||
|
||||
if (dwFlags & MCI_NOTIFY)
|
||||
|
@ -307,6 +374,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 +521,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 +994,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;
|
||||
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;
|
||||
HWND hwnd = lpParms->hWnd ? lpParms->hWnd : wma->window;
|
||||
TRACE("Setting parent window to %p.\n", 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);
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef struct {
|
|||
REFERENCE_TIME seek_stop;
|
||||
UINT command_table;
|
||||
HWND parent;
|
||||
HWND window;
|
||||
MCIDEVICEID notify_devid;
|
||||
HANDLE callback;
|
||||
HANDLE thread;
|
||||
|
|
|
@ -1566,15 +1566,10 @@ 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;
|
||||
ok(video_window != NULL, "Video window should be shown.\n");
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -1588,8 +1583,7 @@ 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, "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. */
|
||||
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_SOURCE, (DWORD_PTR)&parm);
|
||||
|
@ -1623,16 +1617,16 @@ static void test_video_window(void)
|
|||
|
||||
GetWindowRect(video_window, &win_rc);
|
||||
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",
|
||||
wine_dbgstr_rect(&win_rc), wine_dbgstr_rect(&rc));
|
||||
ok(EqualRect(&rc, &win_rc), "Got window rect %s, expected %s.\n",
|
||||
wine_dbgstr_rect(&win_rc), wine_dbgstr_rect(&rc));
|
||||
|
||||
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_WINDOW, (DWORD_PTR)&parm);
|
||||
ok(!err, "Got %s.\n", dbg_mcierr(err));
|
||||
win_rc.right -= win_rc.left;
|
||||
win_rc.bottom -= win_rc.top;
|
||||
ok(EqualRect(&win_rc, &parm.where.rc), "Got rect %s, expected %s.\n",
|
||||
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&win_rc));
|
||||
todo_wine_if (!(style & WS_CHILD))
|
||||
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);
|
||||
ok(!err, "Got %s.\n", dbg_mcierr(err));
|
||||
|
@ -1656,11 +1650,11 @@ static void test_video_window(void)
|
|||
ok(!IsWindowVisible(main_window), "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 be different.\n", video_window, hwnd);
|
||||
ok(hwnd != video_window, "Video window (%p) and child window (%p) should be different.\n",
|
||||
video_window, hwnd);
|
||||
style = GetWindowLongW(hwnd, GWL_STYLE);
|
||||
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);
|
||||
|
||||
style = GetWindowLongW(video_window, GWL_STYLE);
|
||||
|
@ -1687,30 +1681,28 @@ static void test_video_window(void)
|
|||
|
||||
err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (DWORD_PTR)&parm);
|
||||
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",
|
||||
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&rc));
|
||||
ok(EqualRect(&parm.where.rc, &rc), "Got destination rect %s, expected %s.\n",
|
||||
wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&rc));
|
||||
|
||||
/* MCI_PLAY shows current video window */
|
||||
err = mciSendCommandW(id, MCI_PLAY, 0, (DWORD_PTR)&parm);
|
||||
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(!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(id, MCI_WINDOW, MCI_DGV_WINDOW_HWND, (DWORD_PTR)&parm);
|
||||
ok(!err, "Got %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.\n");
|
||||
ok(IsWindowVisible(main_window), "Main 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);
|
||||
ok(!err, "Got %s.\n", dbg_mcierr(err));
|
||||
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));
|
||||
|
||||
next:
|
||||
err = mciSendCommandW(id, MCI_CLOSE, 0, 0);
|
||||
ok(!err, "Got %s.\n", dbg_mcierr(err));
|
||||
|
||||
|
|
Loading…
Reference in a new issue