2 * Common implementation of IVideoWindow
4 * Copyright 2012 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "quartz_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
25 static const WCHAR class_name
[] = L
"wine_quartz_window";
27 static inline struct video_window
*impl_from_IVideoWindow(IVideoWindow
*iface
)
29 return CONTAINING_RECORD(iface
, struct video_window
, IVideoWindow_iface
);
32 static LRESULT CALLBACK
WndProcW(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
34 struct video_window
*window
= (struct video_window
*)GetWindowLongPtrW(hwnd
, 0);
37 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
43 case WM_LBUTTONDBLCLK
:
46 case WM_MBUTTONDBLCLK
:
49 case WM_MOUSEACTIVATE
:
51 case WM_NCLBUTTONDBLCLK
:
52 case WM_NCLBUTTONDOWN
:
54 case WM_NCMBUTTONDBLCLK
:
55 case WM_NCMBUTTONDOWN
:
58 case WM_NCRBUTTONDBLCLK
:
59 case WM_NCRBUTTONDOWN
:
61 case WM_RBUTTONDBLCLK
:
64 if (window
->hwndDrain
)
66 PostMessageW(window
->hwndDrain
, message
, wparam
, lparam
);
71 if (window
->default_dst
)
72 GetClientRect(window
->hwnd
, &window
->dst
);
76 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
79 HRESULT
video_window_create_window(struct video_window
*window
)
81 WNDCLASSW winclass
= {0};
83 winclass
.lpfnWndProc
= WndProcW
;
84 winclass
.cbWndExtra
= sizeof(window
);
85 winclass
.hbrBackground
= GetStockObject(BLACK_BRUSH
);
86 winclass
.lpszClassName
= class_name
;
87 if (!RegisterClassW(&winclass
) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS
)
89 ERR("Unable to register window class: %u\n", GetLastError());
93 if (!(window
->hwnd
= CreateWindowExW(0, class_name
, L
"ActiveMovie Window",
94 WS_OVERLAPPEDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
95 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
96 NULL
, NULL
, NULL
, NULL
)))
98 ERR("Unable to create window\n");
102 SetWindowLongPtrW(window
->hwnd
, 0, (LONG_PTR
)window
);
107 HRESULT WINAPI
BaseControlWindowImpl_QueryInterface(IVideoWindow
*iface
, REFIID iid
, void **out
)
109 struct video_window
*window
= impl_from_IVideoWindow(iface
);
110 return IUnknown_QueryInterface(window
->pFilter
->outer_unk
, iid
, out
);
113 ULONG WINAPI
BaseControlWindowImpl_AddRef(IVideoWindow
*iface
)
115 struct video_window
*window
= impl_from_IVideoWindow(iface
);
116 return IUnknown_AddRef(window
->pFilter
->outer_unk
);
119 ULONG WINAPI
BaseControlWindowImpl_Release(IVideoWindow
*iface
)
121 struct video_window
*window
= impl_from_IVideoWindow(iface
);
122 return IUnknown_Release(window
->pFilter
->outer_unk
);
125 HRESULT WINAPI
BaseControlWindowImpl_GetTypeInfoCount(IVideoWindow
*iface
, UINT
*count
)
127 TRACE("iface %p, count %p.\n", iface
, count
);
132 HRESULT WINAPI
BaseControlWindowImpl_GetTypeInfo(IVideoWindow
*iface
, UINT index
,
133 LCID lcid
, ITypeInfo
**typeinfo
)
135 TRACE("iface %p, index %u, lcid %#x, typeinfo %p.\n", iface
, index
, lcid
, typeinfo
);
136 return strmbase_get_typeinfo(IVideoWindow_tid
, typeinfo
);
139 HRESULT WINAPI
BaseControlWindowImpl_GetIDsOfNames(IVideoWindow
*iface
, REFIID iid
,
140 LPOLESTR
*names
, UINT count
, LCID lcid
, DISPID
*ids
)
145 TRACE("iface %p, iid %s, names %p, count %u, lcid %#x, ids %p.\n",
146 iface
, debugstr_guid(iid
), names
, count
, lcid
, ids
);
148 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IVideoWindow_tid
, &typeinfo
)))
150 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, ids
);
151 ITypeInfo_Release(typeinfo
);
156 HRESULT WINAPI
BaseControlWindowImpl_Invoke(IVideoWindow
*iface
, DISPID id
, REFIID iid
, LCID lcid
,
157 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*error_arg
)
162 TRACE("iface %p, id %d, iid %s, lcid %#x, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
163 iface
, id
, debugstr_guid(iid
), lcid
, flags
, params
, result
, excepinfo
, error_arg
);
165 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IVideoWindow_tid
, &typeinfo
)))
167 hr
= ITypeInfo_Invoke(typeinfo
, iface
, id
, flags
, params
, result
, excepinfo
, error_arg
);
168 ITypeInfo_Release(typeinfo
);
173 HRESULT WINAPI
BaseControlWindowImpl_put_Caption(IVideoWindow
*iface
, BSTR caption
)
175 struct video_window
*window
= impl_from_IVideoWindow(iface
);
177 TRACE("window %p, caption %s.\n", window
, debugstr_w(caption
));
179 if (!SetWindowTextW(window
->hwnd
, caption
))
185 HRESULT WINAPI
BaseControlWindowImpl_get_Caption(IVideoWindow
*iface
, BSTR
*caption
)
187 struct video_window
*window
= impl_from_IVideoWindow(iface
);
191 TRACE("window %p, caption %p.\n", window
, caption
);
195 len
= GetWindowTextLengthW(window
->hwnd
) + 1;
196 if (!(str
= heap_alloc(len
* sizeof(WCHAR
))))
197 return E_OUTOFMEMORY
;
199 GetWindowTextW(window
->hwnd
, str
, len
);
200 *caption
= SysAllocString(str
);
202 return *caption
? S_OK
: E_OUTOFMEMORY
;
205 HRESULT WINAPI
BaseControlWindowImpl_put_WindowStyle(IVideoWindow
*iface
, LONG style
)
207 struct video_window
*window
= impl_from_IVideoWindow(iface
);
209 TRACE("window %p, style %#x.\n", window
, style
);
211 if (style
& (WS_DISABLED
|WS_HSCROLL
|WS_MAXIMIZE
|WS_MINIMIZE
|WS_VSCROLL
))
214 SetWindowLongW(window
->hwnd
, GWL_STYLE
, style
);
215 SetWindowPos(window
->hwnd
, 0, 0, 0, 0, 0,
216 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_FRAMECHANGED
);
220 HRESULT WINAPI
BaseControlWindowImpl_get_WindowStyle(IVideoWindow
*iface
, LONG
*style
)
222 struct video_window
*window
= impl_from_IVideoWindow(iface
);
224 TRACE("window %p, style %p.\n", window
, style
);
226 *style
= GetWindowLongW(window
->hwnd
, GWL_STYLE
);
230 HRESULT WINAPI
BaseControlWindowImpl_put_WindowStyleEx(IVideoWindow
*iface
, LONG style
)
232 struct video_window
*window
= impl_from_IVideoWindow(iface
);
234 TRACE("window %p, style %#x.\n", window
, style
);
236 if (!SetWindowLongW(window
->hwnd
, GWL_EXSTYLE
, style
))
241 HRESULT WINAPI
BaseControlWindowImpl_get_WindowStyleEx(IVideoWindow
*iface
, LONG
*style
)
243 struct video_window
*window
= impl_from_IVideoWindow(iface
);
245 TRACE("window %p, style %p.\n", window
, style
);
247 *style
= GetWindowLongW(window
->hwnd
, GWL_EXSTYLE
);
251 HRESULT WINAPI
BaseControlWindowImpl_put_AutoShow(IVideoWindow
*iface
, LONG AutoShow
)
253 struct video_window
*This
= impl_from_IVideoWindow(iface
);
255 TRACE("(%p/%p)->(%d)\n", This
, iface
, AutoShow
);
257 This
->AutoShow
= AutoShow
;
262 HRESULT WINAPI
BaseControlWindowImpl_get_AutoShow(IVideoWindow
*iface
, LONG
*AutoShow
)
264 struct video_window
*This
= impl_from_IVideoWindow(iface
);
266 TRACE("(%p/%p)->(%p)\n", This
, iface
, AutoShow
);
268 *AutoShow
= This
->AutoShow
;
273 HRESULT WINAPI
BaseControlWindowImpl_put_WindowState(IVideoWindow
*iface
, LONG state
)
275 struct video_window
*window
= impl_from_IVideoWindow(iface
);
277 TRACE("window %p, state %#x.\n", window
, state
);
279 ShowWindow(window
->hwnd
, state
);
283 HRESULT WINAPI
BaseControlWindowImpl_get_WindowState(IVideoWindow
*iface
, LONG
*state
)
285 struct video_window
*window
= impl_from_IVideoWindow(iface
);
288 TRACE("window %p, state %p.\n", window
, state
);
290 style
= GetWindowLongPtrW(window
->hwnd
, GWL_STYLE
);
291 if (!(style
& WS_VISIBLE
))
293 else if (style
& WS_MINIMIZE
)
294 *state
= SW_MINIMIZE
;
295 else if (style
& WS_MAXIMIZE
)
296 *state
= SW_MAXIMIZE
;
303 HRESULT WINAPI
BaseControlWindowImpl_put_BackgroundPalette(IVideoWindow
*iface
, LONG BackgroundPalette
)
305 struct video_window
*This
= impl_from_IVideoWindow(iface
);
307 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, BackgroundPalette
);
312 HRESULT WINAPI
BaseControlWindowImpl_get_BackgroundPalette(IVideoWindow
*iface
, LONG
*pBackgroundPalette
)
314 struct video_window
*This
= impl_from_IVideoWindow(iface
);
316 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pBackgroundPalette
);
321 HRESULT WINAPI
BaseControlWindowImpl_put_Visible(IVideoWindow
*iface
, LONG visible
)
323 struct video_window
*window
= impl_from_IVideoWindow(iface
);
325 TRACE("window %p, visible %d.\n", window
, visible
);
327 ShowWindow(window
->hwnd
, visible
? SW_SHOW
: SW_HIDE
);
331 HRESULT WINAPI
BaseControlWindowImpl_get_Visible(IVideoWindow
*iface
, LONG
*visible
)
333 struct video_window
*window
= impl_from_IVideoWindow(iface
);
335 TRACE("window %p, visible %p.\n", window
, visible
);
340 *visible
= IsWindowVisible(window
->hwnd
) ? OATRUE
: OAFALSE
;
344 HRESULT WINAPI
BaseControlWindowImpl_put_Left(IVideoWindow
*iface
, LONG left
)
346 struct video_window
*window
= impl_from_IVideoWindow(iface
);
349 TRACE("window %p, left %d.\n", window
, left
);
351 GetWindowRect(window
->hwnd
, &rect
);
352 if (!SetWindowPos(window
->hwnd
, NULL
, left
, rect
.top
, 0, 0,
353 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_NOSIZE
))
359 HRESULT WINAPI
BaseControlWindowImpl_get_Left(IVideoWindow
*iface
, LONG
*left
)
361 struct video_window
*window
= impl_from_IVideoWindow(iface
);
364 TRACE("window %p, left %p.\n", window
, left
);
366 GetWindowRect(window
->hwnd
, &rect
);
371 HRESULT WINAPI
BaseControlWindowImpl_put_Width(IVideoWindow
*iface
, LONG width
)
373 struct video_window
*window
= impl_from_IVideoWindow(iface
);
376 TRACE("window %p, width %d.\n", window
, width
);
378 GetWindowRect(window
->hwnd
, &rect
);
379 if (!SetWindowPos(window
->hwnd
, NULL
, 0, 0, width
, rect
.bottom
- rect
.top
,
380 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_NOMOVE
))
386 HRESULT WINAPI
BaseControlWindowImpl_get_Width(IVideoWindow
*iface
, LONG
*width
)
388 struct video_window
*window
= impl_from_IVideoWindow(iface
);
391 TRACE("window %p, width %p.\n", window
, width
);
393 GetWindowRect(window
->hwnd
, &rect
);
394 *width
= rect
.right
- rect
.left
;
398 HRESULT WINAPI
BaseControlWindowImpl_put_Top(IVideoWindow
*iface
, LONG top
)
400 struct video_window
*window
= impl_from_IVideoWindow(iface
);
403 TRACE("window %p, top %d.\n", window
, top
);
405 GetWindowRect(window
->hwnd
, &rect
);
406 if (!SetWindowPos(window
->hwnd
, NULL
, rect
.left
, top
, 0, 0,
407 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_NOSIZE
))
413 HRESULT WINAPI
BaseControlWindowImpl_get_Top(IVideoWindow
*iface
, LONG
*top
)
415 struct video_window
*window
= impl_from_IVideoWindow(iface
);
418 TRACE("window %p, top %p.\n", window
, top
);
420 GetWindowRect(window
->hwnd
, &rect
);
425 HRESULT WINAPI
BaseControlWindowImpl_put_Height(IVideoWindow
*iface
, LONG height
)
427 struct video_window
*window
= impl_from_IVideoWindow(iface
);
430 TRACE("window %p, height %d.\n", window
, height
);
432 GetWindowRect(window
->hwnd
, &rect
);
433 if (!SetWindowPos(window
->hwnd
, NULL
, 0, 0, rect
.right
- rect
.left
,
434 height
, SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_NOMOVE
))
440 HRESULT WINAPI
BaseControlWindowImpl_get_Height(IVideoWindow
*iface
, LONG
*height
)
442 struct video_window
*window
= impl_from_IVideoWindow(iface
);
445 TRACE("window %p, height %p.\n", window
, height
);
447 GetWindowRect(window
->hwnd
, &rect
);
448 *height
= rect
.bottom
- rect
.top
;
452 HRESULT WINAPI
BaseControlWindowImpl_put_Owner(IVideoWindow
*iface
, OAHWND owner
)
454 struct video_window
*window
= impl_from_IVideoWindow(iface
);
455 HWND hwnd
= window
->hwnd
;
457 TRACE("window %p, owner %#lx.\n", window
, owner
);
459 /* Make sure we are marked as WS_CHILD before reparenting ourselves, so that
460 * we do not steal focus. LEGO Island depends on this. */
462 window
->hwndOwner
= (HWND
)owner
;
464 SetWindowLongPtrW(hwnd
, GWL_STYLE
, GetWindowLongPtrW(hwnd
, GWL_STYLE
) | WS_CHILD
);
466 SetWindowLongPtrW(hwnd
, GWL_STYLE
, GetWindowLongPtrW(hwnd
, GWL_STYLE
) & ~WS_CHILD
);
467 SetParent(hwnd
, (HWND
)owner
);
472 HRESULT WINAPI
BaseControlWindowImpl_get_Owner(IVideoWindow
*iface
, OAHWND
*Owner
)
474 struct video_window
*This
= impl_from_IVideoWindow(iface
);
476 TRACE("(%p/%p)->(%p)\n", This
, iface
, Owner
);
478 *(HWND
*)Owner
= This
->hwndOwner
;
483 HRESULT WINAPI
BaseControlWindowImpl_put_MessageDrain(IVideoWindow
*iface
, OAHWND Drain
)
485 struct video_window
*This
= impl_from_IVideoWindow(iface
);
487 TRACE("(%p/%p)->(%08x)\n", This
, iface
, (DWORD
) Drain
);
489 This
->hwndDrain
= (HWND
)Drain
;
494 HRESULT WINAPI
BaseControlWindowImpl_get_MessageDrain(IVideoWindow
*iface
, OAHWND
*Drain
)
496 struct video_window
*This
= impl_from_IVideoWindow(iface
);
498 TRACE("(%p/%p)->(%p)\n", This
, iface
, Drain
);
500 *Drain
= (OAHWND
)This
->hwndDrain
;
505 HRESULT WINAPI
BaseControlWindowImpl_get_BorderColor(IVideoWindow
*iface
, LONG
*Color
)
507 struct video_window
*This
= impl_from_IVideoWindow(iface
);
509 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, Color
);
514 HRESULT WINAPI
BaseControlWindowImpl_put_BorderColor(IVideoWindow
*iface
, LONG Color
)
516 struct video_window
*This
= impl_from_IVideoWindow(iface
);
518 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, Color
);
523 HRESULT WINAPI
BaseControlWindowImpl_get_FullScreenMode(IVideoWindow
*iface
, LONG
*FullScreenMode
)
525 TRACE("(%p)->(%p)\n", iface
, FullScreenMode
);
530 HRESULT WINAPI
BaseControlWindowImpl_put_FullScreenMode(IVideoWindow
*iface
, LONG FullScreenMode
)
532 TRACE("(%p)->(%d)\n", iface
, FullScreenMode
);
536 HRESULT WINAPI
BaseControlWindowImpl_SetWindowForeground(IVideoWindow
*iface
, LONG focus
)
538 struct video_window
*window
= impl_from_IVideoWindow(iface
);
539 UINT flags
= SWP_NOMOVE
| SWP_NOSIZE
;
541 TRACE("window %p, focus %d.\n", window
, focus
);
543 if (focus
!= OAFALSE
&& focus
!= OATRUE
)
546 if (!window
->pPin
->peer
)
547 return VFW_E_NOT_CONNECTED
;
550 flags
|= SWP_NOACTIVATE
;
551 SetWindowPos(window
->hwnd
, HWND_TOP
, 0, 0, 0, 0, flags
);
556 HRESULT WINAPI
BaseControlWindowImpl_SetWindowPosition(IVideoWindow
*iface
,
557 LONG left
, LONG top
, LONG width
, LONG height
)
559 struct video_window
*window
= impl_from_IVideoWindow(iface
);
561 TRACE("window %p, left %d, top %d, width %d, height %d.\n", window
, left
, top
, width
, height
);
563 if (!SetWindowPos(window
->hwnd
, NULL
, left
, top
, width
, height
, SWP_NOACTIVATE
| SWP_NOZORDER
))
568 HRESULT WINAPI
BaseControlWindowImpl_GetWindowPosition(IVideoWindow
*iface
,
569 LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
)
571 struct video_window
*window
= impl_from_IVideoWindow(iface
);
574 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
576 GetWindowRect(window
->hwnd
, &rect
);
579 *width
= rect
.right
- rect
.left
;
580 *height
= rect
.bottom
- rect
.top
;
584 HRESULT WINAPI
BaseControlWindowImpl_NotifyOwnerMessage(IVideoWindow
*iface
,
585 OAHWND hwnd
, LONG message
, LONG_PTR wparam
, LONG_PTR lparam
)
587 struct video_window
*window
= impl_from_IVideoWindow(iface
);
589 TRACE("window %p, hwnd %#lx, message %#x, wparam %#lx, lparam %#lx.\n",
590 window
, hwnd
, message
, wparam
, lparam
);
592 /* That these messages are forwarded, and no others, is stated by the
593 * DirectX documentation, and supported by manual testing. */
597 case WM_DEVMODECHANGE
:
598 case WM_DISPLAYCHANGE
:
599 case WM_PALETTECHANGED
:
600 case WM_PALETTEISCHANGING
:
601 case WM_QUERYNEWPALETTE
:
602 case WM_SYSCOLORCHANGE
:
603 SendMessageW(window
->hwnd
, message
, wparam
, lparam
);
610 HRESULT WINAPI
BaseControlWindowImpl_GetMinIdealImageSize(IVideoWindow
*iface
, LONG
*width
, LONG
*height
)
612 struct video_window
*window
= impl_from_IVideoWindow(iface
);
615 TRACE("window %p, width %p, height %p.\n", window
, width
, height
);
617 rect
= window
->ops
->get_default_rect(window
);
618 *width
= rect
.right
- rect
.left
;
619 *height
= rect
.bottom
- rect
.top
;
623 HRESULT WINAPI
BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow
*iface
, LONG
*width
, LONG
*height
)
625 struct video_window
*window
= impl_from_IVideoWindow(iface
);
628 TRACE("window %p, width %p, height %p.\n", window
, width
, height
);
630 rect
= window
->ops
->get_default_rect(window
);
631 *width
= rect
.right
- rect
.left
;
632 *height
= rect
.bottom
- rect
.top
;
636 HRESULT WINAPI
BaseControlWindowImpl_GetRestorePosition(IVideoWindow
*iface
, LONG
*pLeft
, LONG
*pTop
, LONG
*pWidth
, LONG
*pHeight
)
638 struct video_window
*This
= impl_from_IVideoWindow(iface
);
640 FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
645 HRESULT WINAPI
BaseControlWindowImpl_HideCursor(IVideoWindow
*iface
, LONG HideCursor
)
647 struct video_window
*This
= impl_from_IVideoWindow(iface
);
649 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, HideCursor
);
654 HRESULT WINAPI
BaseControlWindowImpl_IsCursorHidden(IVideoWindow
*iface
, LONG
*CursorHidden
)
656 struct video_window
*This
= impl_from_IVideoWindow(iface
);
658 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, CursorHidden
);
663 static inline struct video_window
*impl_from_IBasicVideo(IBasicVideo
*iface
)
665 return CONTAINING_RECORD(iface
, struct video_window
, IBasicVideo_iface
);
668 static HRESULT WINAPI
basic_video_QueryInterface(IBasicVideo
*iface
, REFIID iid
, void **out
)
670 struct video_window
*window
= impl_from_IBasicVideo(iface
);
671 return IUnknown_QueryInterface(window
->pFilter
->outer_unk
, iid
, out
);
674 static ULONG WINAPI
basic_video_AddRef(IBasicVideo
*iface
)
676 struct video_window
*window
= impl_from_IBasicVideo(iface
);
677 return IUnknown_AddRef(window
->pFilter
->outer_unk
);
680 static ULONG WINAPI
basic_video_Release(IBasicVideo
*iface
)
682 struct video_window
*window
= impl_from_IBasicVideo(iface
);
683 return IUnknown_Release(window
->pFilter
->outer_unk
);
686 static HRESULT WINAPI
basic_video_GetTypeInfoCount(IBasicVideo
*iface
, UINT
*count
)
688 TRACE("iface %p, count %p.\n", iface
, count
);
693 static HRESULT WINAPI
basic_video_GetTypeInfo(IBasicVideo
*iface
, UINT index
,
694 LCID lcid
, ITypeInfo
**typeinfo
)
696 TRACE("iface %p, index %u, lcid %#x, typeinfo %p.\n", iface
, index
, lcid
, typeinfo
);
697 return strmbase_get_typeinfo(IBasicVideo_tid
, typeinfo
);
700 static HRESULT WINAPI
basic_video_GetIDsOfNames(IBasicVideo
*iface
, REFIID iid
,
701 LPOLESTR
*names
, UINT count
, LCID lcid
, DISPID
*ids
)
706 TRACE("iface %p, iid %s, names %p, count %u, lcid %#x, ids %p.\n",
707 iface
, debugstr_guid(iid
), names
, count
, lcid
, ids
);
709 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IBasicVideo_tid
, &typeinfo
)))
711 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, ids
);
712 ITypeInfo_Release(typeinfo
);
717 static HRESULT WINAPI
basic_video_Invoke(IBasicVideo
*iface
, DISPID id
, REFIID iid
, LCID lcid
,
718 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*error_arg
)
723 TRACE("iface %p, id %d, iid %s, lcid %#x, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
724 iface
, id
, debugstr_guid(iid
), lcid
, flags
, params
, result
, excepinfo
, error_arg
);
726 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IBasicVideo_tid
, &typeinfo
)))
728 hr
= ITypeInfo_Invoke(typeinfo
, iface
, id
, flags
, params
, result
, excepinfo
, error_arg
);
729 ITypeInfo_Release(typeinfo
);
734 static const VIDEOINFOHEADER
*get_video_format(struct video_window
*window
)
736 /* Members of VIDEOINFOHEADER up to bmiHeader are identical to those of
737 * VIDEOINFOHEADER2. */
738 return (const VIDEOINFOHEADER
*)window
->pPin
->mt
.pbFormat
;
741 static const BITMAPINFOHEADER
*get_bitmap_header(struct video_window
*window
)
743 const AM_MEDIA_TYPE
*mt
= &window
->pPin
->mt
;
744 if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
745 return &((VIDEOINFOHEADER
*)mt
->pbFormat
)->bmiHeader
;
747 return &((VIDEOINFOHEADER2
*)mt
->pbFormat
)->bmiHeader
;
750 static HRESULT WINAPI
basic_video_get_AvgTimePerFrame(IBasicVideo
*iface
, REFTIME
*reftime
)
752 struct video_window
*window
= impl_from_IBasicVideo(iface
);
756 if (!window
->pPin
->peer
)
757 return VFW_E_NOT_CONNECTED
;
759 TRACE("window %p, reftime %p.\n", window
, reftime
);
761 *reftime
= (double)get_video_format(window
)->AvgTimePerFrame
/ 1e7
;
765 static HRESULT WINAPI
basic_video_get_BitRate(IBasicVideo
*iface
, LONG
*rate
)
767 struct video_window
*window
= impl_from_IBasicVideo(iface
);
769 TRACE("window %p, rate %p.\n", window
, rate
);
773 if (!window
->pPin
->peer
)
774 return VFW_E_NOT_CONNECTED
;
776 *rate
= get_video_format(window
)->dwBitRate
;
780 static HRESULT WINAPI
basic_video_get_BitErrorRate(IBasicVideo
*iface
, LONG
*rate
)
782 struct video_window
*window
= impl_from_IBasicVideo(iface
);
784 TRACE("window %p, rate %p.\n", window
, rate
);
788 if (!window
->pPin
->peer
)
789 return VFW_E_NOT_CONNECTED
;
791 *rate
= get_video_format(window
)->dwBitErrorRate
;
795 static HRESULT WINAPI
basic_video_get_VideoWidth(IBasicVideo
*iface
, LONG
*width
)
797 struct video_window
*window
= impl_from_IBasicVideo(iface
);
799 TRACE("window %p, width %p.\n", window
, width
);
804 *width
= get_bitmap_header(window
)->biWidth
;
809 static HRESULT WINAPI
basic_video_get_VideoHeight(IBasicVideo
*iface
, LONG
*height
)
811 struct video_window
*window
= impl_from_IBasicVideo(iface
);
813 TRACE("window %p, height %p.\n", window
, height
);
818 *height
= abs(get_bitmap_header(window
)->biHeight
);
823 static HRESULT WINAPI
basic_video_put_SourceLeft(IBasicVideo
*iface
, LONG left
)
825 struct video_window
*window
= impl_from_IBasicVideo(iface
);
827 TRACE("window %p, left %d.\n", window
, left
);
829 if (left
< 0 || window
->src
.right
+ left
- window
->src
.left
> get_bitmap_header(window
)->biWidth
)
832 OffsetRect(&window
->src
, left
- window
->src
.left
, 0);
836 static HRESULT WINAPI
basic_video_get_SourceLeft(IBasicVideo
*iface
, LONG
*left
)
838 struct video_window
*window
= impl_from_IBasicVideo(iface
);
840 TRACE("window %p, left %p.\n", window
, left
);
845 *left
= window
->src
.left
;
849 static HRESULT WINAPI
basic_video_put_SourceWidth(IBasicVideo
*iface
, LONG width
)
851 struct video_window
*window
= impl_from_IBasicVideo(iface
);
853 TRACE("window %p, width %d.\n", window
, width
);
855 if (width
<= 0 || window
->src
.left
+ width
> get_bitmap_header(window
)->biWidth
)
858 window
->src
.right
= window
->src
.left
+ width
;
862 static HRESULT WINAPI
basic_video_get_SourceWidth(IBasicVideo
*iface
, LONG
*width
)
864 struct video_window
*window
= impl_from_IBasicVideo(iface
);
866 TRACE("window %p, width %p.\n", window
, width
);
871 *width
= window
->src
.right
- window
->src
.left
;
875 static HRESULT WINAPI
basic_video_put_SourceTop(IBasicVideo
*iface
, LONG top
)
877 struct video_window
*window
= impl_from_IBasicVideo(iface
);
879 TRACE("window %p, top %d.\n", window
, top
);
881 if (top
< 0 || window
->src
.bottom
+ top
- window
->src
.top
> get_bitmap_header(window
)->biHeight
)
884 OffsetRect(&window
->src
, 0, top
- window
->src
.top
);
888 static HRESULT WINAPI
basic_video_get_SourceTop(IBasicVideo
*iface
, LONG
*top
)
890 struct video_window
*window
= impl_from_IBasicVideo(iface
);
892 TRACE("window %p, top %p.\n", window
, top
);
897 *top
= window
->src
.top
;
901 static HRESULT WINAPI
basic_video_put_SourceHeight(IBasicVideo
*iface
, LONG height
)
903 struct video_window
*window
= impl_from_IBasicVideo(iface
);
905 TRACE("window %p, height %d.\n", window
, height
);
907 if (height
<= 0 || window
->src
.top
+ height
> get_bitmap_header(window
)->biHeight
)
910 window
->src
.bottom
= window
->src
.top
+ height
;
914 static HRESULT WINAPI
basic_video_get_SourceHeight(IBasicVideo
*iface
, LONG
*height
)
916 struct video_window
*window
= impl_from_IBasicVideo(iface
);
918 TRACE("window %p, height %p\n", window
, height
);
923 *height
= window
->src
.bottom
- window
->src
.top
;
927 static HRESULT WINAPI
basic_video_put_DestinationLeft(IBasicVideo
*iface
, LONG left
)
929 struct video_window
*window
= impl_from_IBasicVideo(iface
);
931 TRACE("window %p, left %d.\n", window
, left
);
933 window
->default_dst
= FALSE
;
934 OffsetRect(&window
->dst
, left
- window
->dst
.left
, 0);
938 static HRESULT WINAPI
basic_video_get_DestinationLeft(IBasicVideo
*iface
, LONG
*left
)
940 struct video_window
*window
= impl_from_IBasicVideo(iface
);
942 TRACE("window %p, left %p.\n", window
, left
);
947 *left
= window
->dst
.left
;
951 static HRESULT WINAPI
basic_video_put_DestinationWidth(IBasicVideo
*iface
, LONG width
)
953 struct video_window
*window
= impl_from_IBasicVideo(iface
);
955 TRACE("window %p, width %d.\n", window
, width
);
960 window
->default_dst
= FALSE
;
961 window
->dst
.right
= window
->dst
.left
+ width
;
965 static HRESULT WINAPI
basic_video_get_DestinationWidth(IBasicVideo
*iface
, LONG
*width
)
967 struct video_window
*window
= impl_from_IBasicVideo(iface
);
969 TRACE("window %p, width %p.\n", window
, width
);
974 *width
= window
->dst
.right
- window
->dst
.left
;
978 static HRESULT WINAPI
basic_video_put_DestinationTop(IBasicVideo
*iface
, LONG top
)
980 struct video_window
*window
= impl_from_IBasicVideo(iface
);
982 TRACE("window %p, top %d.\n", window
, top
);
984 window
->default_dst
= FALSE
;
985 OffsetRect(&window
->dst
, 0, top
- window
->dst
.top
);
989 static HRESULT WINAPI
basic_video_get_DestinationTop(IBasicVideo
*iface
, LONG
*top
)
991 struct video_window
*window
= impl_from_IBasicVideo(iface
);
993 TRACE("window %p, top %p.\n", window
, top
);
998 *top
= window
->dst
.top
;
1002 static HRESULT WINAPI
basic_video_put_DestinationHeight(IBasicVideo
*iface
, LONG height
)
1004 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1006 TRACE("window %p, height %d.\n", window
, height
);
1009 return E_INVALIDARG
;
1011 window
->default_dst
= FALSE
;
1012 window
->dst
.bottom
= window
->dst
.top
+ height
;
1016 static HRESULT WINAPI
basic_video_get_DestinationHeight(IBasicVideo
*iface
, LONG
*height
)
1018 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1020 TRACE("window %p, height %p.\n", window
, height
);
1025 *height
= window
->dst
.bottom
- window
->dst
.top
;
1029 static HRESULT WINAPI
basic_video_SetSourcePosition(IBasicVideo
*iface
,
1030 LONG left
, LONG top
, LONG width
, LONG height
)
1032 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1033 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1035 TRACE("window %p, left %d, top %d, width %d, height %d.\n", window
, left
, top
, width
, height
);
1037 if (left
< 0 || left
+ width
> bitmap_header
->biWidth
|| width
<= 0)
1038 return E_INVALIDARG
;
1039 if (top
< 0 || top
+ height
> bitmap_header
->biHeight
|| height
<= 0)
1040 return E_INVALIDARG
;
1042 SetRect(&window
->src
, left
, top
, left
+ width
, top
+ height
);
1046 static HRESULT WINAPI
basic_video_GetSourcePosition(IBasicVideo
*iface
,
1047 LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
)
1049 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1051 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
1053 if (!left
|| !top
|| !width
|| !height
)
1056 *left
= window
->src
.left
;
1057 *top
= window
->src
.top
;
1058 *width
= window
->src
.right
- window
->src
.left
;
1059 *height
= window
->src
.bottom
- window
->src
.top
;
1063 static HRESULT WINAPI
basic_video_SetDefaultSourcePosition(IBasicVideo
*iface
)
1065 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1066 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1068 TRACE("window %p.\n", window
);
1070 SetRect(&window
->src
, 0, 0, bitmap_header
->biWidth
, bitmap_header
->biHeight
);
1074 static HRESULT WINAPI
basic_video_SetDestinationPosition(IBasicVideo
*iface
,
1075 LONG left
, LONG top
, LONG width
, LONG height
)
1077 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1079 TRACE("window %p, left %d, top %d, width %d, height %d.\n", window
, left
, top
, width
, height
);
1081 if (width
<= 0 || height
<= 0)
1082 return E_INVALIDARG
;
1084 window
->default_dst
= FALSE
;
1085 SetRect(&window
->dst
, left
, top
, left
+ width
, top
+ height
);
1089 static HRESULT WINAPI
basic_video_GetDestinationPosition(IBasicVideo
*iface
,
1090 LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
)
1092 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1094 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
1096 if (!left
|| !top
|| !width
|| !height
)
1099 *left
= window
->dst
.left
;
1100 *top
= window
->dst
.top
;
1101 *width
= window
->dst
.right
- window
->dst
.left
;
1102 *height
= window
->dst
.bottom
- window
->dst
.top
;
1106 static HRESULT WINAPI
basic_video_SetDefaultDestinationPosition(IBasicVideo
*iface
)
1108 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1110 TRACE("window %p.\n", window
);
1112 window
->default_dst
= TRUE
;
1113 GetClientRect(window
->hwnd
, &window
->dst
);
1117 static HRESULT WINAPI
basic_video_GetVideoSize(IBasicVideo
*iface
, LONG
*width
, LONG
*height
)
1119 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1120 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1122 TRACE("window %p, width %p, height %p.\n", window
, width
, height
);
1124 if (!width
|| !height
)
1127 *width
= bitmap_header
->biWidth
;
1128 *height
= bitmap_header
->biHeight
;
1132 static HRESULT WINAPI
basic_video_GetVideoPaletteEntries(IBasicVideo
*iface
,
1133 LONG start
, LONG count
, LONG
*ret_count
, LONG
*palette
)
1135 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1137 FIXME("window %p, start %d, count %d, ret_count %p, palette %p, stub!\n",
1138 window
, start
, count
, ret_count
, palette
);
1140 if (!ret_count
|| !palette
)
1144 return VFW_E_NO_PALETTE_AVAILABLE
;
1147 static HRESULT WINAPI
basic_video_GetCurrentImage(IBasicVideo
*iface
, LONG
*size
, LONG
*image
)
1149 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1151 TRACE("window %p, size %p, image %p.\n", window
, size
, image
);
1153 if (!size
|| !image
)
1156 return window
->ops
->get_current_image(window
, size
, image
);
1159 static HRESULT WINAPI
basic_video_IsUsingDefaultSource(IBasicVideo
*iface
)
1161 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1162 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1164 TRACE("window %p.\n", window
);
1166 if (!window
->src
.left
&& !window
->src
.top
1167 && window
->src
.right
== bitmap_header
->biWidth
1168 && window
->src
.bottom
== bitmap_header
->biHeight
)
1173 static HRESULT WINAPI
basic_video_IsUsingDefaultDestination(IBasicVideo
*iface
)
1175 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1177 TRACE("window %p.\n", window
);
1179 return window
->default_dst
? S_OK
: S_FALSE
;
1182 static const IBasicVideoVtbl basic_video_vtbl
=
1184 basic_video_QueryInterface
,
1186 basic_video_Release
,
1187 basic_video_GetTypeInfoCount
,
1188 basic_video_GetTypeInfo
,
1189 basic_video_GetIDsOfNames
,
1191 basic_video_get_AvgTimePerFrame
,
1192 basic_video_get_BitRate
,
1193 basic_video_get_BitErrorRate
,
1194 basic_video_get_VideoWidth
,
1195 basic_video_get_VideoHeight
,
1196 basic_video_put_SourceLeft
,
1197 basic_video_get_SourceLeft
,
1198 basic_video_put_SourceWidth
,
1199 basic_video_get_SourceWidth
,
1200 basic_video_put_SourceTop
,
1201 basic_video_get_SourceTop
,
1202 basic_video_put_SourceHeight
,
1203 basic_video_get_SourceHeight
,
1204 basic_video_put_DestinationLeft
,
1205 basic_video_get_DestinationLeft
,
1206 basic_video_put_DestinationWidth
,
1207 basic_video_get_DestinationWidth
,
1208 basic_video_put_DestinationTop
,
1209 basic_video_get_DestinationTop
,
1210 basic_video_put_DestinationHeight
,
1211 basic_video_get_DestinationHeight
,
1212 basic_video_SetSourcePosition
,
1213 basic_video_GetSourcePosition
,
1214 basic_video_SetDefaultSourcePosition
,
1215 basic_video_SetDestinationPosition
,
1216 basic_video_GetDestinationPosition
,
1217 basic_video_SetDefaultDestinationPosition
,
1218 basic_video_GetVideoSize
,
1219 basic_video_GetVideoPaletteEntries
,
1220 basic_video_GetCurrentImage
,
1221 basic_video_IsUsingDefaultSource
,
1222 basic_video_IsUsingDefaultDestination
1225 void video_window_unregister_class(void)
1227 if (!UnregisterClassW(class_name
, NULL
) && GetLastError() != ERROR_CLASS_DOES_NOT_EXIST
)
1228 ERR("Failed to unregister class, error %u.\n", GetLastError());
1231 void video_window_init(struct video_window
*window
, const IVideoWindowVtbl
*vtbl
,
1232 struct strmbase_filter
*owner
, struct strmbase_pin
*pin
, const struct video_window_ops
*ops
)
1234 memset(window
, 0, sizeof(*window
));
1236 window
->IVideoWindow_iface
.lpVtbl
= vtbl
;
1237 window
->IBasicVideo_iface
.lpVtbl
= &basic_video_vtbl
;
1238 window
->default_dst
= TRUE
;
1239 window
->AutoShow
= OATRUE
;
1240 window
->pFilter
= owner
;
1244 void video_window_cleanup(struct video_window
*window
)
1248 /* Media Player Classic deadlocks if WM_PARENTNOTIFY is sent, so clear
1249 * the child style first. Just like Windows, we don't actually unparent
1250 * the window, to prevent extra focus events from being generated since
1251 * it would become top-level for a brief period before being destroyed. */
1252 SetWindowLongW(window
->hwnd
, GWL_STYLE
, GetWindowLongW(window
->hwnd
, GWL_STYLE
) & ~WS_CHILD
);
1254 SendMessageW(window
->hwnd
, WM_CLOSE
, 0, 0);
1255 window
->hwnd
= NULL
;