Jacek Caban : wmp: Added DoVerb(OLEIVERB_INPLACEACTIVATE) implementation.

Alexandre Julliard julliard at winehq.org
Thu Feb 20 10:08:11 CST 2014


Module: wine
Branch: master
Commit: 79fc46ddbb7c89c7c25a4c5a893f4f92cccdb1ba
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=79fc46ddbb7c89c7c25a4c5a893f4f92cccdb1ba

Author: Jacek Caban <jacek at 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);




More information about the wine-cvs mailing list