Module: wine Branch: master Commit: 79fc46ddbb7c89c7c25a4c5a893f4f92cccdb1ba URL: http://source.winehq.org/git/wine.git/?a=commit;h=79fc46ddbb7c89c7c25a4c5a89...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Feb 20 16:01:45 2014 +0100
wmp: Added DoVerb(OLEIVERB_INPLACEACTIVATE) implementation.
---
dlls/wmp/Makefile.in | 1 + dlls/wmp/oleobj.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/wmp_main.c | 5 +- dlls/wmp/wmp_private.h | 5 ++ 4 files changed, 197 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/Makefile.in b/dlls/wmp/Makefile.in index a4d07c1..a82cc36 100644 --- a/dlls/wmp/Makefile.in +++ b/dlls/wmp/Makefile.in @@ -1,4 +1,5 @@ MODULE = wmp.dll +IMPORTS = user32 gdi32
C_SRCS = \ oleobj.c \ diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c index a6daabb..7074bd6 100644 --- a/dlls/wmp/oleobj.c +++ b/dlls/wmp/oleobj.c @@ -23,11 +23,189 @@
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
+static HWND get_container_hwnd(WindowsMediaPlayer *This) +{ + IOleWindow *ole_window; + HWND hwnd = NULL; + HRESULT hres; + + /* IOleInPlaceSite (which inherits from IOleWindow) is prefered. */ + hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSite, (void**)&ole_window); + if(FAILED(hres)) { + hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleWindow, (void**)&ole_window); + if(FAILED(hres)) { + IOleContainer *container = NULL; + + hres = IOleClientSite_GetContainer(This->client_site, &container); + if(SUCCEEDED(hres)) { + hres = IOleContainer_QueryInterface(container, &IID_IOleWindow, (void**)&ole_window); + IOleContainer_Release(container); + } + } + } + + if(FAILED(hres)) + return NULL; + + hres = IOleWindow_GetWindow(ole_window, &hwnd); + IOleWindow_Release(ole_window); + if(FAILED(hres)) + return NULL; + + TRACE("Got window %p\n", hwnd); + return hwnd; +} + +static LRESULT WINAPI wmp_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_PAINT: { + PAINTSTRUCT ps; + HFONT font; + RECT rect; + HDC hdc; + + TRACE("WM_PAINT\n"); + + GetClientRect(hwnd, &rect); + hdc = BeginPaint(hwnd, &ps); + + SelectObject(hdc, GetStockObject(DC_BRUSH)); + SetDCBrushColor(hdc, RGB(255,0,0)); + SetBkColor(hdc, RGB(255,0,0)); + + font = CreateFontA(25,0,0,0,400,0,0,0,ANSI_CHARSET,0,0,DEFAULT_QUALITY,DEFAULT_PITCH,NULL); + SelectObject(hdc, font); + + Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); + DrawTextA(hdc, "FIXME: WMP", -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER); + + DeleteObject(font); + EndPaint(hwnd, &ps); + break; + } + } + + return DefWindowProcW(hwnd, msg, wParam, lParam); + +} + +static ATOM wmp_class; + +static BOOL WINAPI register_wmp_class(INIT_ONCE *once, void *param, void **context) +{ + /* It seems that native uses ATL for this. We use a fake name to make tests happy. */ + static const WCHAR atl_wmpW[] = {'A','T','L',':','W','M','P',0}; + + static WNDCLASSEXW wndclass = { + sizeof(wndclass), CS_DBLCLKS, wmp_wnd_proc, 0, 0, + NULL, NULL, NULL, NULL, NULL, + atl_wmpW, NULL + }; + + wndclass.hInstance = wmp_instance; + wmp_class = RegisterClassExW(&wndclass); + return TRUE; +} + +void unregister_wmp_class(void) +{ + if(wmp_class) + UnregisterClassW(MAKEINTRESOURCEW(wmp_class), wmp_instance); +} + +static HWND create_wmp_window(WindowsMediaPlayer *wmp, const RECT *posrect) +{ + static INIT_ONCE class_init_once = INIT_ONCE_STATIC_INIT; + + InitOnceExecuteOnce(&class_init_once, register_wmp_class, NULL, NULL); + if(!wmp_class) + return NULL; + + return CreateWindowExW(0, MAKEINTRESOURCEW(wmp_class), NULL, WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE|WS_CHILD, + posrect->left, posrect->top, posrect->right-posrect->left, posrect->bottom-posrect->top, + get_container_hwnd(wmp), NULL, wmp_instance, NULL); +} + +static HRESULT activate_inplace(WindowsMediaPlayer *This) +{ + IOleInPlaceSiteWindowless *ipsite_windowless; + IOleInPlaceSiteEx *ipsiteex = NULL; + IOleInPlaceSite *ipsite; + IOleInPlaceUIWindow *ip_window = NULL; + IOleInPlaceFrame *ip_frame = NULL; + RECT posrect = {0}, cliprect = {0}; + OLEINPLACEFRAMEINFO frameinfo = { sizeof(frameinfo) }; + HRESULT hres; + + if(This->hwnd) { + FIXME("Already activated\n"); + return E_UNEXPECTED; + } + + hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSiteWindowless, (void**)&ipsite_windowless); + if(SUCCEEDED(hres)) { + hres = IOleInPlaceSiteWindowless_CanWindowlessActivate(ipsite_windowless); + IOleInPlaceSiteWindowless_Release(ipsite_windowless); + if(hres == S_OK) + FIXME("Windowless activation not supported\n"); + ipsiteex = (IOleInPlaceSiteEx*)ipsite_windowless; + }else { + IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSiteEx, (void**)&ipsiteex); + } + + if(ipsiteex) { + BOOL redraw = FALSE; /* Not really used. */ + IOleInPlaceSiteEx_OnInPlaceActivateEx(ipsiteex, &redraw, 0); + ipsite = (IOleInPlaceSite*)ipsiteex; + }else { + IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSite, (void**)&ipsite); + if(FAILED(hres)) { + FIXME("No IOleInPlaceSite instance\n"); + return hres; + } + + IOleInPlaceSite_OnInPlaceActivate(ipsite); + } + + hres = IOleInPlaceSite_GetWindowContext(ipsite, &ip_frame, &ip_window, &posrect, &cliprect, &frameinfo); + IOleInPlaceSite_Release(ipsite); + if(FAILED(hres)) { + FIXME("GetWindowContext failed: %08x\n", hres); + return hres; + } + + This->hwnd = create_wmp_window(This, &posrect); + if(!This->hwnd) + return E_FAIL; + + IOleClientSite_ShowObject(This->client_site); + return S_OK; +} + +static void deactivate_window(WindowsMediaPlayer *This) +{ + IOleInPlaceSite *ip_site; + HRESULT hres; + + hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSite, (void**)&ip_site); + if(SUCCEEDED(hres)) { + IOleInPlaceSite_OnInPlaceDeactivate(ip_site); + IOleInPlaceSite_Release(ip_site); + } + + DestroyWindow(This->hwnd); + This->hwnd = NULL; +} + static void release_client_site(WindowsMediaPlayer *This) { if(!This->client_site) return;
+ if(This->hwnd) + deactivate_window(This); + IOleClientSite_Release(This->client_site); This->client_site = NULL; } @@ -206,7 +384,15 @@ static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpms LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) { WindowsMediaPlayer *This = impl_from_IOleObject(iface); - FIXME("(%p)->(%d %p %p %d %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect); + + switch(iVerb) { + case OLEIVERB_INPLACEACTIVATE: + TRACE("(%p)->(OLEIVERB_INPLACEACTIVATE)\n", This); + return activate_inplace(This); + default: + FIXME("Unsupported iVerb %d\n", iVerb); + } + return E_NOTIMPL; }
diff --git a/dlls/wmp/wmp_main.c b/dlls/wmp/wmp_main.c index 995c08e..29b096f 100644 --- a/dlls/wmp/wmp_main.c +++ b/dlls/wmp/wmp_main.c @@ -24,7 +24,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
-static HINSTANCE wmp_instance; +HINSTANCE wmp_instance;
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { @@ -89,6 +89,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) DisableThreadLibraryCalls(hInstDLL); wmp_instance = hInstDLL; break; + case DLL_PROCESS_DETACH: + unregister_wmp_class(); + break; }
return TRUE; diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 8f1a85a..11d4c22 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -33,12 +33,17 @@ struct WindowsMediaPlayer { LONG ref;
IOleClientSite *client_site; + HWND hwnd; };
void init_player_ifaces(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
+void unregister_wmp_class(void) DECLSPEC_HIDDEN; + +extern HINSTANCE wmp_instance; + static inline void *heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len);