]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/ole/activex.cpp
Fix wxHtmlHelpData::SetTempDir() to behave correctly without trailing slash.
[wxWidgets.git] / src / msw / ole / activex.cpp
index caacde5b4f510582dc755656a21c66e40d2d3ab4..654fe80c3a59e5bf10beb21cacaf22ed9782f9f7 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
 // Modified by:
 // Created:     11/07/04
-// RCS-ID:      $Id$
 // Copyright:   (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 #include "wx/msw/private.h" // for wxCopyRectToRECT
 
 // autointerfaces that we only use here
-WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite)
-WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument)
-WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit)
-WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink)
-WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo, IProvideClassInfo)
-WX_DECLARE_AUTOOLE(wxAutoITypeInfo, ITypeInfo)
-WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint, IConnectionPoint)
-WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer, IConnectionPointContainer)
+typedef wxAutoOleInterface<IOleInPlaceSite> wxAutoIOleInPlaceSite;
+typedef wxAutoOleInterface<IOleDocument> wxAutoIOleDocument;
+typedef wxAutoOleInterface<IPersistStreamInit> wxAutoIPersistStreamInit;
+typedef wxAutoOleInterface<IAdviseSink> wxAutoIAdviseSink;
+typedef wxAutoOleInterface<IProvideClassInfo> wxAutoIProvideClassInfo;
+typedef wxAutoOleInterface<ITypeInfo> wxAutoITypeInfo;
+typedef wxAutoOleInterface<IConnectionPoint> wxAutoIConnectionPoint;
+typedef wxAutoOleInterface<IConnectionPointContainer> wxAutoIConnectionPointContainer;
 
-wxDEFINE_EVENT( wxEVT_ACTIVEX, wxActiveXEvent )
+wxDEFINE_EVENT( wxEVT_ACTIVEX, wxActiveXEvent );
 
 // Ole class helpers (sort of MFC-like) from wxActiveX
 #define DECLARE_OLE_UNKNOWN(cls)\
@@ -54,7 +53,7 @@ wxDEFINE_EVENT( wxEVT_ACTIVEX, wxActiveXEvent )
     {\
         public:\
         LONG l;\
-        TAutoInitInt() : l(0) {}\
+        TAutoInitInt() : l(1) {}\
     };\
     TAutoInitInt refCount, lockCount;\
     static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
@@ -354,7 +353,7 @@ public:
     HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
     {
         // TODO: send an event with this id
-        if (m_window->m_oleInPlaceActiveObject.Ok())
+        if (m_window->m_oleInPlaceActiveObject.IsOk())
             m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
         return S_FALSE;
     }
@@ -425,7 +424,7 @@ public:
     HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; }
     HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
     {
-        if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
+        if (m_window->m_oleInPlaceObject.IsOk() && lprcPosRect)
         {
            //
            // Result of several hours and days of bug hunting -
@@ -606,7 +605,7 @@ public:
     {
         wxAutoIOleInPlaceSite inPlaceSite(
             IID_IOleInPlaceSite, (IDispatch *) this);
-        if (!inPlaceSite.Ok())
+        if (!inPlaceSite.IsOk())
             return E_FAIL;
 
         if (pViewToActivate)
@@ -618,7 +617,7 @@ public:
         {
             wxAutoIOleDocument oleDoc(
                 IID_IOleDocument, m_window->m_oleObject);
-            if (! oleDoc.Ok())
+            if (! oleDoc.IsOk())
                 return E_FAIL;
 
             HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
@@ -633,6 +632,10 @@ public:
         return S_OK;
     }
 
+    friend bool QueryClientSiteInterface(FrameSite *self, REFIID iid, void **_interface, const char *&desc)
+    {
+        return self->m_window->QueryClientSiteInterface(iid,_interface,desc);
+    }
 
 protected:
     wxActiveXContainer * m_window;
@@ -670,6 +673,7 @@ DEFINE_OLE_TABLE(FrameSite)
     OLE_IINTERFACE(IOleDocumentSite)
     OLE_IINTERFACE(IAdviseSink)
     OLE_IINTERFACE(IOleControlSite)
+    OLE_INTERFACE_CUSTOM(QueryClientSiteInterface)
 END_OLE_TABLE
 
 
@@ -699,8 +703,7 @@ public:
     // wxVariants containing a void* to this variables are 'empty' in the sense
     // that the actual ActiveX OLE parameter has not been converted and inserted
     // into m_params.
-    static const int ptr_invalid_entry_marker = 0;
-    static wxVariant g_invalid_entry_marker;
+    static wxVariant ms_invalidEntryMarker;
 
     wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
     wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_customId(iid), m_haveCustomId(true) {}
@@ -766,8 +769,8 @@ public:
             if (params_index < event.m_params.GetCount()) {
                 wxVariant &vx = event.m_params[params_index];
                 // copy the result back to pDispParams only if the event has been accessed
-                //  i.e.  if vx != g_invalid_entry_marker
-                if (!vx.IsType(wxActiveXEvents::g_invalid_entry_marker.GetType()) || vx!=g_invalid_entry_marker) {
+                //  i.e.  if vx != ms_invalidEntryMarker
+                if (!vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) || vx!=ms_invalidEntryMarker) {
                     VARIANTARG& va = pDispParams->rgvarg[i];
                     wxConvertVariantToOle(vx, va);
                 }
@@ -781,7 +784,13 @@ public:
     }
 };
 
-wxVariant wxActiveXEvents::g_invalid_entry_marker((void*)&wxActiveXEvents::ptr_invalid_entry_marker);
+namespace
+{
+// just a unique global variable
+const int invalid_entry_marker = 0;
+}
+
+wxVariant wxActiveXEvents::ms_invalidEntryMarker((void*)&invalid_entry_marker);
 
 size_t wxActiveXEvent::ParamCount() const
 {
@@ -802,12 +811,17 @@ wxVariant &wxActiveXEvent::operator [](size_t idx)
     // 'native' will always be != if the event has been created
     // for an actual active X event.
     // But it may be zero if the event has been created by wx program code.
-    if (native) {
-        while (m_params.GetCount()<=idx) {
-            m_params.Append(wxActiveXEvents::g_invalid_entry_marker);
+    if (native)
+    {
+        while ( m_params.GetCount()<=idx )
+        {
+            m_params.Append(wxActiveXEvents::ms_invalidEntryMarker);
         }
-        wxVariant &vx(m_params[idx]);
-        if (vx.IsType(wxActiveXEvents::g_invalid_entry_marker.GetType()) && vx==wxActiveXEvents::g_invalid_entry_marker) {
+
+        wxVariant& vx = m_params[idx];
+        if ( vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) &&
+                vx == wxActiveXEvents::ms_invalidEntryMarker)
+        {
             // copy the _real_ parameter into this one
             // NOTE: m_params stores the parameters in *reverse* order.
             // Whyever, but this was the case in the original implementation of
@@ -825,7 +839,6 @@ bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interfa
 {
     if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
     {
-//        WXOLE_TRACE("Found Custom Dispatch Interface");
         *_interface = (IUnknown *) (IDispatch *) self;
         desc = "Custom Dispatch Interface";
         return true;
@@ -869,13 +882,13 @@ wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
 wxActiveXContainer::~wxActiveXContainer()
 {
     // disconnect connection points
-    if (m_oleInPlaceObject.Ok())
+    if (m_oleInPlaceObject.IsOk())
     {
         m_oleInPlaceObject->InPlaceDeactivate();
         m_oleInPlaceObject->UIDeactivate();
     }
 
-    if (m_oleObject.Ok())
+    if (m_oleObject.IsOk())
     {
         if (m_docAdviseCookie != 0)
             m_oleObject->Unadvise(m_docAdviseCookie);
@@ -895,10 +908,10 @@ wxActiveXContainer::~wxActiveXContainer()
 }
 
 // VZ: we might want to really report an error instead of just asserting here
-#ifdef __WXDEBUG__
+#if wxDEBUG_LEVEL
     #define CHECK_HR(hr) \
-        wxASSERT_MSG( SUCCEEDED(hr), \
-            wxString::Format("HRESULT = %X", (unsigned)(hr)) )
+        wxASSERT_LEVEL_2_MSG( SUCCEEDED(hr), \
+                wxString::Format("HRESULT = %X", (unsigned)(hr)) )
 #else
     #define CHECK_HR(hr) wxUnusedVar(hr)
 #endif
@@ -925,7 +938,7 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
     CHECK_HR(hret);
     // adviseSink
     wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) m_frameSite);
-    wxASSERT(adviseSink.Ok());
+    wxASSERT(adviseSink.IsOk());
 
     // Get Dispatch interface
     hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
@@ -937,13 +950,13 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
 
     // get type info via class info
     wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
-    wxASSERT(classInfo.Ok());
+    wxASSERT(classInfo.IsOk());
 
     // type info
     wxAutoITypeInfo typeInfo;
     hret = classInfo->GetClassInfo(typeInfo.GetRef());
     CHECK_HR(hret);
-    wxASSERT(typeInfo.Ok());
+    wxASSERT(typeInfo.IsOk());
 
     // TYPEATTR
     TYPEATTR *ta = NULL;
@@ -966,7 +979,7 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
         // get dispatch type info interface
         wxAutoITypeInfo  ti;
         hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
-        if (! ti.Ok())
+        if (! ti.IsOk())
             continue;
 
         CHECK_HR(hret);
@@ -1007,17 +1020,31 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
                 DWORD                    adviseCookie = 0;
 
                 wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
-                wxASSERT( cpContainer.Ok());
+                wxASSERT( cpContainer.IsOk());
 
                 HRESULT hret =
                     cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
-                CHECK_HR(hret);
 
-                IDispatch* disp;
-                m_frameSite->QueryInterface(IID_IDispatch, (void**)&disp);
-                hret = cp->Advise(new wxActiveXEvents(this, ta->guid),
-                                  &adviseCookie);
-                CHECK_HR(hret);
+                // Notice that the return value of CONNECT_E_NOCONNECTION is
+                // expected if the interface doesn't support connection points.
+                if ( hret != CONNECT_E_NOCONNECTION )
+                {
+                    CHECK_HR(hret);
+                }
+
+                if ( cp )
+                {
+                    wxActiveXEvents * const
+                        events = new wxActiveXEvents(this, ta->guid);
+                    hret = cp->Advise(events, &adviseCookie);
+
+                    // We don't need this object any more and cp will keep a
+                    // reference to it if it needs it, i.e. if Advise()
+                    // succeeded.
+                    events->Release();
+
+                    CHECK_HR(hret);
+                }
             }
         }
 
@@ -1070,7 +1097,7 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
     wxAutoIPersistStreamInit
         pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
 
-    if (pPersistStreamInit.Ok())
+    if (pPersistStreamInit.IsOk())
     {
         hret = pPersistStreamInit->InitNew();
         CHECK_HR(hret);
@@ -1082,35 +1109,35 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
 
     m_oleObjectHWND = 0;
 
-    if (m_oleInPlaceObject.Ok())
-    {
-        hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
-        if (SUCCEEDED(hret))
-            ::SetActiveWindow(m_oleObjectHWND);
-    }
-
 
     if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
     {
         RECT posRect;
         wxCopyRectToRECT(m_realparent->GetClientSize(), posRect);
 
+        hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
+            m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
+        CHECK_HR(hret);
+
+        if (m_oleInPlaceObject.IsOk())
+        {
+            hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
+            CHECK_HR(hret);
+            ::SetActiveWindow(m_oleObjectHWND);
+        }
+
         if (posRect.right > 0 && posRect.bottom > 0 &&
-            m_oleInPlaceObject.Ok())
+            m_oleInPlaceObject.IsOk())
         {
             m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
         }
 
-        hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
-            m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
-        CHECK_HR(hret);
-
         hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
             (HWND)m_realparent->GetHWND(), &posRect);
         CHECK_HR(hret);
     }
 
-    if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
+    if (! m_oleObjectHWND && m_oleInPlaceObject.IsOk())
     {
         hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
         CHECK_HR(hret);
@@ -1155,14 +1182,12 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
     posRect.right = w;
     posRect.bottom = h;
 
-    if (w <= 0 && h <= 0)
+    if (w <= 0 || h <= 0)
         return;
 
     // extents are in HIMETRIC units
-    if (m_oleObject.Ok())
+    if (m_oleObject.IsOk())
     {
-        m_oleObject->DoVerb(OLEIVERB_HIDE, 0, m_clientSite, 0,
-            (HWND)m_realparent->GetHWND(), &posRect);
 
         SIZEL sz = {w, h};
         PixelsToHimetric(sz);
@@ -1173,11 +1198,9 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
         if (sz2.cx !=  sz.cx || sz.cy != sz2.cy)
             m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
 
-        m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
-            (HWND)m_realparent->GetHWND(), &posRect);
     }
 
-    if (m_oleInPlaceObject.Ok())
+    if (m_oleInPlaceObject.IsOk())
         m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
 
     event.Skip();
@@ -1221,7 +1244,7 @@ void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
 //---------------------------------------------------------------------------
 void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
 {
-    if (m_oleInPlaceActiveObject.Ok())
+    if (m_oleInPlaceActiveObject.IsOk())
         m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
 
     event.Skip();
@@ -1235,10 +1258,39 @@ void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
 //---------------------------------------------------------------------------
 void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
 {
-    if (m_oleInPlaceActiveObject.Ok())
+    if (m_oleInPlaceActiveObject.IsOk())
         m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
 
     event.Skip();
 }
 
+//---------------------------------------------------------------------------
+// wxActiveXContainer::MSWTranslateMessage
+//
+// Called for every message that needs to be translated.
+// Some controls might need more keyboard keys to process (CTRL-C, CTRL-A etc),
+// In that case TranslateAccelerator should always be called first.
+//---------------------------------------------------------------------------
+bool wxActiveXContainer::MSWTranslateMessage(WXMSG* pMsg)
+{
+    if(m_oleInPlaceActiveObject.IsOk() && m_oleInPlaceActiveObject->TranslateAccelerator(pMsg) == S_OK)
+    {
+        return true;
+    }
+    return wxWindow::MSWTranslateMessage(pMsg);
+}
+
+//---------------------------------------------------------------------------
+// wxActiveXContainer::QueryClientSiteInterface
+//
+// Called in the host's site's query method for other interfaces.
+//---------------------------------------------------------------------------
+bool wxActiveXContainer::QueryClientSiteInterface(REFIID iid, void **_interface, const char *&desc)
+{
+    wxUnusedVar(iid);
+    wxUnusedVar(_interface);
+    wxUnusedVar(desc);
+    return false;
+}
+
 #endif // wxUSE_ACTIVEX