[PATCH v2 1/6] mciqtz32: Simplify video window management by creating default window.

Akihiro Sagawa wine at gitlab.winehq.org
Tue Jul 5 06:34:21 CDT 2022


From: Akihiro Sagawa <sagawa.aki at gmail.com>

Now the video 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 at gmail.com>
---
 dlls/mciqtz32/mciqtz.c         | 162 +++++++++++++++++++++++++--------
 dlls/mciqtz32/mciqtz_private.h |   1 +
 2 files changed, 127 insertions(+), 36 deletions(-)

diff --git a/dlls/mciqtz32/mciqtz.c b/dlls/mciqtz32/mciqtz.c
index a7ec0b78f33..92622d848a9 100644
--- a/dlls/mciqtz32/mciqtz.c
+++ b/dlls/mciqtz32/mciqtz.c
@@ -31,8 +31,11 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(mciqtz);
 
+#define MCIQTZ_CLASS L"MCIQTZ_Window"
+
 static DWORD MCIQTZ_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS);
 static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
+static DWORD MCIQTZ_mciPause(UINT, DWORD, LPMCI_GENERIC_PARMS);
 
 /*======================================================================*
  *                          MCI QTZ implementation                      *
@@ -68,6 +71,62 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID)
     return wma;
 }
 
+static LRESULT WINAPI MCIQTZ_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    TRACE("hwnd=%p msg=%x wparam=%Ix lparam=%Ix\n", hWnd, uMsg, wParam, lParam);
+
+    switch (uMsg) {
+    case WM_CREATE:
+    {
+        LPARAM wDevId = (LPARAM)((CREATESTRUCTW *)lParam)->lpCreateParams;
+        SetWindowLongW(hWnd, 0, wDevId);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+    }
+
+    case WM_CLOSE:
+    {
+        MCIQTZ_mciPause(GetWindowLongW(hWnd, 0), MCI_WAIT, NULL);
+        ShowWindow(hWnd, SW_HIDE);
+        return 0;
+    }
+
+    case WM_ERASEBKGND:
+    {
+        RECT	rect;
+        GetClientRect(hWnd, &rect);
+        FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
+        return 1;
+    }
+
+    default:
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+    }
+}
+
+static BOOL MCIQTZ_UnregisterClass(void)
+{
+    return UnregisterClassW(MCIQTZ_CLASS, MCIQTZ_hInstance);
+}
+
+static BOOL MCIQTZ_RegisterClass(void)
+{
+    WNDCLASSW wndClass;
+
+    ZeroMemory(&wndClass, sizeof(WNDCLASSW));
+    wndClass.style         = CS_DBLCLKS;
+    wndClass.lpfnWndProc   = MCIQTZ_WindowProc;
+    wndClass.cbWndExtra    = sizeof(MCIDEVICEID);
+    wndClass.hInstance     = MCIQTZ_hInstance;
+    wndClass.hCursor       = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
+    wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
+    wndClass.lpszClassName = MCIQTZ_CLASS;
+
+    if (RegisterClassW(&wndClass)) return TRUE;
+    if (GetLastError() == ERROR_CLASS_ALREADY_EXISTS) return TRUE;
+
+    return FALSE;
+}
+
 /**************************************************************************
  *                              MCIQTZ_drvOpen                  [internal]
  */
@@ -81,6 +140,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 +170,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 +201,54 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID)
     return 1;
 }
 
+static BOOL MCIQTZ_CreateWindow(WINE_MCIQTZ* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSW lpParms)
+{
+    HWND	hParent = NULL;
+    DWORD	dwStyle = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) & ~WS_MAXIMIZEBOX;
+    RECT        rc;
+    HRESULT     hr;
+
+    /* what should be done ? */
+    if (wma->window) return TRUE;
+
+    if (dwFlags & MCI_DGV_OPEN_PARENT)	hParent = lpParms->hWndParent;
+    if (dwFlags & MCI_DGV_OPEN_WS)	dwStyle = lpParms->dwStyle;
+
+    dwStyle &= ~WS_VISIBLE;
+
+    rc.left = rc.top = 0;
+    hr = IBasicVideo_GetVideoSize(wma->vidbasic, &rc.right, &rc.bottom);
+    if (FAILED(hr)) return hr == E_NOINTERFACE; /* no video renderer ? */
+
+    AdjustWindowRect(&rc, dwStyle, FALSE);
+    if (!(dwStyle & (WS_CHILD|WS_POPUP))) /* overlapped window ? */
+    {
+        rc.right -= rc.left;
+        rc.bottom -= rc.top;
+        rc.left = rc.top = CW_USEDEFAULT;
+    }
+
+    wma->window = CreateWindowW(MCIQTZ_CLASS, lpParms->lpstrElementName, dwStyle,
+                                rc.left, rc.top, rc.right, rc.bottom,
+                                hParent, 0, MCIQTZ_hInstance,
+                                ULongToPtr(wma->wDevID));
+
+    TRACE("(%04x, %08lX, %p, style %lx, parent %p, dimensions %ldx%ld, window %p)\n", wma->wDevID,
+          dwFlags, lpParms, dwStyle, hParent, rc.right - (rc.left == CW_USEDEFAULT ? 0 : rc.left), rc.bottom - (rc.top == CW_USEDEFAULT ? 0 : rc.top), wma->window);
+
+    if (!wma->window)
+        return FALSE;
+
+    wma->parent = wma->window;
+    IVideoWindow_put_AutoShow(wma->vidwin, OAFALSE);
+    IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)wma->parent);
+    IVideoWindow_put_WindowStyle(wma->vidwin, WS_CHILD);
+    IVideoWindow_put_Owner(wma->vidwin, (OAHWND)wma->parent);
+    IVideoWindow_put_Visible(wma->vidwin, OATRUE);
+
+    return TRUE;
+}
+
 /**************************************************************************
  *                              MCIQTZ_mciNotify                [internal]
  *
@@ -161,8 +271,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 +346,7 @@ 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);
+    MCIQTZ_CreateWindow(wma, dwFlags, lpOpenParms);
     wma->opened = TRUE;
 
     if (dwFlags & MCI_NOTIFY)
@@ -307,6 +400,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 +547,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);
 
     wma->thread = CreateThread(NULL, 0, MCIQTZ_notifyThread, wma, 0, NULL);
     if (!wma->thread) {
@@ -525,9 +626,6 @@ static DWORD MCIQTZ_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
         wma->thread = NULL;
     }
 
-    if (!wma->parent)
-        IVideoWindow_put_Visible(wma->vidwin, OAFALSE);
-
     return 0;
 }
 
@@ -574,6 +672,9 @@ static DWORD MCIQTZ_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lp
         return MCIERR_INTERNAL;
     }
 
+    if (wma->parent)
+        ShowWindow(wma->parent, SW_SHOW);
+
     return 0;
 }
 
@@ -919,21 +1020,10 @@ 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;
+        wma->parent = lpParms->hWnd ? lpParms->hWnd : wma->window;
+        IVideoWindow_put_MessageDrain(wma->vidwin, (OAHWND)wma->parent);
+        IVideoWindow_put_Owner(wma->vidwin, (OAHWND)wma->parent);
     }
     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;
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/370



More information about the wine-devel mailing list