#include "wxActiveX.h"
#include <wx/strconv.h>
-#include <wx/msw/ole/uuid.h>
+#include <wx/event.h>
#include <oleidl.h>
#include <winerror.h>
#include <idispids.h>
#endif
#endif
+
//////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(wxActiveX, wxWindow)
- EVT_SIZE(OnSize)
- EVT_SET_FOCUS(OnSetFocus)
- EVT_KILL_FOCUS(OnKillFocus)
+ EVT_SIZE(wxActiveX::OnSize)
+ EVT_PAINT(wxActiveX::OnPaint)
+ EVT_MOUSE_EVENTS(wxActiveX::OnMouse)
+ EVT_SET_FOCUS(wxActiveX::OnSetFocus)
+ EVT_KILL_FOCUS(wxActiveX::OnKillFocus)
END_EVENT_TABLE()
class wxActiveX;
public:
FrameSite(wxActiveX * win);
- ~FrameSite();
+ virtual ~FrameSite();
//IOleWindow
STDMETHODIMP GetWindow(HWND*);
wxActiveX::wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& name) :
- wxWindow(parent, id, pos, size, style, name)
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name) :
+wxWindow(parent, id, pos, size, style, name)
{
- m_bAmbientUserMode = true;
+ m_bAmbientUserMode = true;
m_docAdviseCookie = 0;
- CreateActiveX(clsid);
+ CreateActiveX(clsid);
}
wxActiveX::wxActiveX(wxWindow * parent, wxString progId, wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& name) :
- wxWindow(parent, id, pos, size, style, name)
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name) :
+ wxWindow(parent, id, pos, size, style, name)
{
- m_bAmbientUserMode = true;
+ m_bAmbientUserMode = true;
m_docAdviseCookie = 0;
- CreateActiveX((LPOLESTR) wxConvUTF8.cMB2WC(progId).data());
+ CreateActiveX((LPOLESTR) (const wchar_t *) progId.wc_str(wxConvUTF8));
}
wxActiveX::~wxActiveX()
wxASSERT(adviseSink.Ok());
-
-
// // Create Object, get IUnknown interface
m_ActiveX.CreateInstance(clsid, IID_IUnknown);
wxASSERT(m_ActiveX.Ok());
+ // Type Info
+ GetTypeInfo();
+
// Get IOleObject interface
hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
wxASSERT(SUCCEEDED(hret));
- // Get IOleInPlaceObject interface
+
+ // get IViewObject Interface
+ hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
+ wxASSERT(SUCCEEDED(hret));
+
+ // document advise
+ m_docAdviseCookie = 0;
+ hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
+ WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")");
+ m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
+ OleSetContainedObject(m_oleObject, TRUE);
+ OleRun(m_oleObject);
+
+
+ // Get IOleInPlaceObject interface
hret = m_oleInPlaceObject.QueryInterface(IID_IOleInPlaceObject, m_ActiveX);
wxASSERT(SUCCEEDED(hret));
WXOLE_WARN(hret, "CreateActiveX::pPersistStreamInit->InitNew()");
};
- // document advise
- m_docAdviseCookie = 0;
- hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
- WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")");
- m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
- OleSetContainedObject(m_oleObject, TRUE);
-
if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
m_oleObject->SetClientSite(m_clientSite);
posRect.bottom = h;
m_oleObjectHWND = 0;
- hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
- WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
- if (SUCCEEDED(hret))
- ::SetActiveWindow(m_oleObjectHWND);
+
+ if (m_oleInPlaceObject.Ok())
+ {
+ hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
+ WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
+ if (SUCCEEDED(hret))
+ ::SetActiveWindow(m_oleObjectHWND);
+ };
if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
{
- m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
+ if (w > 0 && h > 0 && m_oleInPlaceObject.Ok())
+ m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, m_clientSite, 0, (HWND)GetHWND(), &posRect);
hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, (HWND)GetHWND(), &posRect);
};
+ if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
+ {
+ hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
+ WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
+ };
+
+ if (m_oleObjectHWND)
+ {
+ ::SetActiveWindow(m_oleObjectHWND);
+ ::ShowWindow(m_oleObjectHWND, SW_SHOW);
+ };
}
void wxActiveX::CreateActiveX(LPOLESTR progId)
CreateActiveX(clsid);
};
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Case Insensitive Map of Event names to eventTypes
+// created dynamically at run time in:
+// EVT_ACTIVEX(eventName, id, fn)
+// we map the pointer to them so that:
+// const wxEventType& RegisterActiveXEvent(wxString eventName);
+// can return a const reference, which is neccessary for event tables
+// probably should use a wxWindows hash table here, but I'm lazy ...
+struct less_wxStringI
+{
+ bool operator()(const wxString& x, const wxString& y) const
+ {
+ return x.CmpNoCase(y) < 0;
+ };
+};
+
+typedef map<wxString, wxEventType *, less_wxStringI> ActiveXNamedEventMap;
+static ActiveXNamedEventMap sg_NamedEventMap;
+
+const wxEventType& RegisterActiveXEvent(const wxChar *eventName)
+{
+ wxString ev = eventName;
+ ActiveXNamedEventMap::iterator it = sg_NamedEventMap.find(ev);
+ if (it == sg_NamedEventMap.end())
+ {
+ wxEventType *et = new wxEventType(wxNewEventType());
+ sg_NamedEventMap[ev] = et;
+
+ return *et;
+ };
+
+ return *(it->second);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Map of Event DISPID's to eventTypes
+// created dynamically at run time in:
+// EVT_ACTIVEX(eventName, id, fn)
+// we map the pointer to them so that:
+// const wxEventType& RegisterActiveXEvent(wxString eventName);
+// can return a const reference, which is neccessary for event tables
+
+typedef map<DISPID, wxEventType *> ActiveXDISPIDEventMap;
+static ActiveXDISPIDEventMap sg_dispIdEventMap;
+
+const wxEventType& RegisterActiveXEvent(DISPID event)
+{
+ ActiveXDISPIDEventMap::iterator it = sg_dispIdEventMap.find(event);
+ if (it == sg_dispIdEventMap.end())
+ {
+ wxEventType *et = new wxEventType(wxNewEventType());
+ sg_dispIdEventMap[event] = et;
+
+ return *et;
+ };
+
+ return *(it->second);
+};
+
+// one off class for automatic freeing of activeX eventtypes
+class ActiveXEventMapFlusher
+{
+public:
+ ~ActiveXEventMapFlusher()
+ {
+ // Named events
+ ActiveXNamedEventMap::iterator it = sg_NamedEventMap.end();
+ while (it != sg_NamedEventMap.end())
+ {
+ delete it->second;
+ it++;
+ };
+
+ // DISPID events
+ ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.end();
+ while (dit != sg_dispIdEventMap.end())
+ {
+ delete dit->second;
+ dit++;
+ };
+ };
+};
+
+static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher;
+
+
+//////////////////////////////////////////////////////
+bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx)
+{
+ switch(va.vt)
+ {
+ case VT_VARIANT | VT_BYREF:
+ return MSWVariantToVariant(*va.pvarVal, vx);
+
+ case VT_I2:
+ case VT_I4:
+ vx = (long) va.iVal;
+ return true;
+
+ case VT_I2 | VT_BYREF:
+ case VT_I4 | VT_BYREF:
+ vx = (long) *va.piVal;
+ return true;
+
+ case VT_BSTR:
+ vx = wxString(va.bstrVal);
+ return true;
+
+ case VT_BSTR | VT_BYREF:
+ vx = wxString(*va.pbstrVal);
+ return true;
+
+ case VT_BOOL:
+ vx = (va.boolVal != FALSE);
+ return true;
+
+ case VT_BOOL | VT_BYREF:
+ vx = (*va.pboolVal != FALSE);
+ return true;
+
+ default:
+ vx.MakeNull();
+ return false;
+ };
+};
+
+bool VariantToMSWVariant(wxVariant& vx, VARIANTARG& va)
+{
+ switch(va.vt)
+ {
+ case VT_VARIANT | VT_BYREF:
+ return VariantToMSWVariant(vx, va);
+
+ case VT_I2:
+ case VT_I4:
+ va.iVal = (long) vx;
+ return true;
+
+ case VT_I2 | VT_BYREF:
+ case VT_I4 | VT_BYREF:
+ *va.piVal = (long) vx;
+ return true;
+
+ case VT_BOOL:
+ va.boolVal = ((bool) vx) ? TRUE : FALSE;
+ return true;
+
+ case VT_BOOL | VT_BYREF:
+ *va.pboolVal = ((bool) vx) ? TRUE : FALSE;
+ return true;
+
+ default:
+ return false;
+ };
+};
+
+class wxActiveXEvents : public IDispatch
+{
+private:
+ DECLARE_OLE_UNKNOWN(wxActiveXEvents);
+
+
+ wxActiveX *m_activeX;
+
+public:
+ wxActiveXEvents(wxActiveX *ax) : m_activeX(ax) {}
+ virtual ~wxActiveXEvents()
+ {
+ }
+
+ //IDispatch
+ STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d)
+ {
+ return E_NOTIMPL;
+ };
+
+ STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t)
+ {
+ return E_NOTIMPL;
+ };
+
+ STDMETHODIMP GetTypeInfoCount(unsigned int* i)
+ {
+ return E_NOTIMPL;
+ };
+
+
+ void DispatchEvent(int eventIdx, const wxEventType& eventType, DISPPARAMS * pDispParams)
+ {
+ wxASSERT(eventIdx >= 0 && eventIdx < int(m_activeX->m_events.size()));
+ wxActiveX::FuncX &func = m_activeX->m_events[eventIdx];
+
+ wxActiveXEvent event;
+ event.SetId(m_activeX->GetId());
+ event.SetEventType(eventType);
+ event.m_params.NullList();
+ event.m_params.SetName(func.name);
+
+ // arguments
+ if (pDispParams)
+ {
+ // cdecl call
+ // sometimes the pDispParams does not match the param info for a activex control
+ int nArg = wxMin(func.params.size(), pDispParams->cArgs);
+ for (int i = nArg - 1; i >= 0; i--)
+ {
+ VARIANTARG& va = pDispParams->rgvarg[i];
+ wxActiveX::ParamX &px = func.params[nArg - i - 1];
+ wxVariant vx;
+
+ vx.SetName(px.name);
+ MSWVariantToVariant(va, vx);
+ event.m_params.Append(vx);
+ };
+ };
+
+ if (func.hasOut)
+ {
+ int nArg = wxMin(func.params.size(), pDispParams->cArgs);
+ m_activeX->GetParent()->ProcessEvent(event);
+ for (int i = 0; i < nArg; i++)
+ {
+ VARIANTARG& va = pDispParams->rgvarg[i];
+ wxActiveX::ParamX &px = func.params[nArg - i - 1];
+
+ if (px.IsOut())
+ {
+ wxVariant& vx = event.m_params[nArg - i - 1];
+
+ VariantToMSWVariant(vx, va);
+ };
+ };
+ }
+ else
+ m_activeX->GetParent()->AddPendingEvent(event);
+
+ };
+
+ STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
+ WORD wFlags, DISPPARAMS * pDispParams,
+ VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
+ unsigned int * puArgErr)
+ {
+ if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
+ return E_NOTIMPL;
+
+ wxASSERT(m_activeX);
+
+ // map dispid to m_eventsIdx
+ wxActiveX::MemberIdList::iterator mid = m_activeX->m_eventsIdx.find((MEMBERID) dispIdMember);
+ if (mid == m_activeX->m_eventsIdx.end())
+ return S_OK;
+
+ int funcIdx = mid->second;
+ wxActiveX::FuncX &func = m_activeX->m_events[funcIdx];
+
+
+ // try to find dispid event
+ ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.find(dispIdMember);
+ if (dit != sg_dispIdEventMap.end())
+ {
+ // Dispatch Event
+ DispatchEvent(funcIdx, *(dit->second), pDispParams);
+ return S_OK;
+ };
+
+ // try named event
+ ActiveXNamedEventMap::iterator nit = sg_NamedEventMap.find(func.name);
+ if (nit == sg_NamedEventMap.end())
+ return S_OK;
+
+ // Dispatch Event
+ DispatchEvent(funcIdx, *(nit->second), pDispParams);
+ return S_OK;
+ }
+};
+
+
+DEFINE_OLE_TABLE(wxActiveXEvents)
+ OLE_IINTERFACE(IUnknown)
+ OLE_INTERFACE(IID_IDispatch, IDispatch)
+END_OLE_TABLE;
+
+wxString wxActiveXEvent::EventName()
+{
+ return m_params.GetName();
+};
+
+int wxActiveXEvent::ParamCount() const
+{
+ return m_params.GetCount();
+};
+
+wxString wxActiveXEvent::ParamType(int idx)
+{
+ wxASSERT(idx >= 0 && idx < m_params.GetCount());
+
+ return m_params[idx].GetType();
+};
+
+wxString wxActiveXEvent::ParamName(int idx)
+{
+ wxASSERT(idx >= 0 && idx < m_params.GetCount());
+
+ return m_params[idx].GetName();
+};
+
+static wxVariant nullVar;
+
+wxVariant wxActiveXEvent::operator[] (int idx) const
+{
+ return (wxVariant&) operator[] (idx);
+};
+
+wxVariant& wxActiveXEvent::operator[] (int idx)
+{
+ wxASSERT(idx >= 0 && idx < ParamCount());
+
+ return m_params[idx];
+};
+
+wxVariant wxActiveXEvent::operator[] (wxString name) const
+{
+ return (wxVariant&) operator[] (name);
+};
+
+wxVariant& wxActiveXEvent::operator[] (wxString name)
+{
+ for (int i = 0; i < m_params.GetCount(); i++)
+ {
+ if (name.CmpNoCase(m_params[i].GetName()) == 0)
+ return m_params[i];
+ };
+
+ wxString err = wxT("wxActiveXEvent::operator[] invalid name <") + name + wxT(">");
+ err += wxT("\r\nValid Names = :\r\n");
+ for (i = 0; i < m_params.GetCount(); i++)
+ {
+ err += m_params[i].GetName();
+ err += wxT("\r\n");
+ };
+
+ wxASSERT_MSG(false, err);
+
+ return nullVar;
+};
+
+void wxActiveX::GetTypeInfo()
+{
+ /*
+ We are currently only interested in the IDispatch interface
+ to the control. For dual interfaces (TypeKind = TKIND_INTERFACE)
+ we should drill down through the inheritance
+ (using TYPEATTR->cImplTypes) and GetRefTypeOfImplType(n)
+ and retrieve all the func names etc that way, then generate a C++
+ header file for it.
+
+ But we don't do this and probably never will, so if we have a DUAL
+ interface then we query for the IDispatch
+ via GetRefTypeOfImplType(-1).
+ */
+
+ HRESULT hret = 0;
+
+ // get type info via class info
+ wxAutoOleInterface<IProvideClassInfo> classInfo(IID_IProvideClassInfo, m_ActiveX);
+ if (! classInfo.Ok())
+ return;
+
+ // type info
+ wxAutoOleInterface<ITypeInfo> typeInfo;
+ hret = classInfo->GetClassInfo(typeInfo.GetRef());
+ if (! typeInfo.Ok())
+ return;
+
+ // TYPEATTR
+ TYPEATTR *ta = NULL;
+ hret = typeInfo->GetTypeAttr(&ta);
+ if (! ta)
+ return;
+
+ // this should be a TKIND_COCLASS
+ wxASSERT(ta->typekind == TKIND_COCLASS);
+
+ // iterate contained interfaces
+ for (int i = 0; i < ta->cImplTypes; i++)
+ {
+ HREFTYPE rt = 0;
+
+ // get dispatch type info handle
+ hret = typeInfo->GetRefTypeOfImplType(i, &rt);
+ if (! SUCCEEDED(hret))
+ continue;
+
+ // get dispatch type info interface
+ wxAutoOleInterface<ITypeInfo> ti;
+ hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
+ if (! ti.Ok())
+ continue;
+
+ // check if default event sink
+ bool defEventSink = false;
+ int impTypeFlags = 0;
+ typeInfo->GetImplTypeFlags(i, &impTypeFlags);
+
+ if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
+ {
+ if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
+ {
+ WXOLE_TRACEOUT(wxT("Default Event Sink"));
+ defEventSink = true;
+ }
+ else
+ {
+ WXOLE_TRACEOUT(wxT("Default Interface"));
+ }
+ };
+
+
+ // process
+ GetTypeInfo(ti, defEventSink);
+ };
+
+
+ // free
+ typeInfo->ReleaseTypeAttr(ta);
+};
+
+void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink)
+{
+ ti->AddRef();
+ wxAutoOleInterface<ITypeInfo> typeInfo(ti);
+
+ // TYPEATTR
+ TYPEATTR *ta = NULL;
+ HRESULT hret = typeInfo->GetTypeAttr(&ta);
+ if (! ta)
+ return;
+
+ if (ta->typekind == TKIND_DISPATCH)
+ {
+ WXOLE_TRACEOUT(wxT("GUID = ") << GetIIDName(ta->guid).c_str());
+
+ if (defEventSink)
+ {
+ wxActiveXEvents *disp = new wxActiveXEvents(this);
+ ConnectAdvise(ta->guid, disp);
+ };
+
+
+ // Get Function Names
+ for (int i = 0; i < ta->cFuncs; i++)
+ {
+ FUNCDESC FAR *fd = NULL;
+
+ hret = typeInfo->GetFuncDesc(i, &fd);
+ if (! fd)
+ continue;
+
+ BSTR anames[1] = {NULL};
+ unsigned int n = 0;
+
+ hret = typeInfo->GetNames(fd->memid, anames, 1, &n);
+
+ if (anames[0])
+ {
+ wxString name = anames[0];
+
+ WXOLE_TRACEOUT(wxT("Name ") << i << wxT(" = ") << name.c_str());
+ SysFreeString(anames[0]);
+
+ if (defEventSink)
+ {
+ FuncX func;
+ func.name = name;
+ func.memid = fd->memid;
+ func.hasOut = false;
+
+ // get Param Names
+ unsigned int maxPNames = fd->cParams + 1;
+ unsigned int nPNames = 0;
+ BSTR *pnames = new BSTR[maxPNames];
+
+ hret = typeInfo->GetNames(fd->memid, pnames, maxPNames, &nPNames);
+ wxASSERT(int(nPNames) >= fd->cParams + 1);
+
+ SysFreeString(pnames[0]);
+ // params
+ for (int p = 0; p < fd->cParams; p++)
+ {
+ ParamX param;
+
+ param.flags = fd->lprgelemdescParam[p].idldesc.wIDLFlags;
+ param.vt = fd->lprgelemdescParam[p].tdesc.vt;
+ param.isPtr = (param.vt == VT_PTR);
+ param.isSafeArray = (param.vt == VT_SAFEARRAY);
+ if (param.isPtr || param.isSafeArray)
+ param.vt = fd->lprgelemdescParam[p].tdesc.lptdesc->vt;
+
+ param.name = pnames[p + 1];
+ SysFreeString(pnames[p + 1]);
+
+ func.hasOut |= (param.IsOut() || param.isPtr);
+ func.params.push_back(param);
+ };
+ delete [] pnames;
+
+ m_events.push_back(func);
+ m_eventsIdx[fd->memid] = m_events.size() - 1;
+ };
+ };
+
+ typeInfo->ReleaseFuncDesc(fd);
+ };
+ }
+
+ typeInfo->ReleaseTypeAttr(ta);
+};
+
+///////////////////////////////////////////////
+// Type Info exposure
+const wxActiveX::FuncX& wxActiveX::GetEvent(int idx) const
+{
+ wxASSERT(idx >= 0 && idx < GetEventCount());
+
+ return m_events[idx];
+};
+
+///////////////////////////////////////////////
+
HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events)
{
wxOleConnectionPoint cp;
posRect.right = w;
posRect.bottom = h;
- if (m_oleInPlaceObject)
- m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
+ if (w <= 0 && h <= 0)
+ return;
// extents are in HIMETRIC units
- SIZEL sz = {w, h};
- PixelsToHimetric(sz);
+ if (m_oleObject.Ok())
+ {
+ SIZEL sz = {w, h};
+ PixelsToHimetric(sz);
- SIZEL sz2;
- m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
- if (sz2.cx != sz.cx || sz.cy != sz2.cy)
- m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
+ SIZEL sz2;
+
+ m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
+ if (sz2.cx != sz.cx || sz.cy != sz2.cy)
+ m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
+ };
+
+ if (m_oleInPlaceObject.Ok())
+ m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
}
+void wxActiveX::OnPaint(wxPaintEvent& event)
+{
+// wxLogTrace(wxT("repainting activex win"));
+ wxPaintDC dc(this);
+ dc.BeginDrawing();
+ int w, h;
+ GetSize(&w, &h);
+ RECT posRect;
+ posRect.left = 0;
+ posRect.top = 0;
+ posRect.right = w;
+ posRect.bottom = h;
+
+ // Draw only when control is windowless or deactivated
+ if (m_viewObject)
+ {
+ ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
+ {
+ RECTL *prcBounds = (RECTL *) &posRect;
+ m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
+ (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
+ }
+ }
+ else
+ {
+ dc.SetBrush(*wxRED_BRUSH);
+ dc.DrawRectangle(0, 0, w, h);
+ dc.SetBrush(wxNullBrush);
+ }
+ dc.EndDrawing();
+}
+
+
+void wxActiveX::OnMouse(wxMouseEvent& event)
+{
+ if (m_oleObjectHWND == NULL)
+ {
+// wxLogTrace(wxT("no oleInPlaceObject"));
+ event.Skip();
+ return;
+ }
+
+// wxLogTrace(wxT("mouse event"));
+ UINT msg = 0;
+ WPARAM wParam = 0;
+ LPARAM lParam = 0;
+ LRESULT lResult = 0;
+
+ if (event.m_metaDown)
+ wParam |= MK_CONTROL;
+ if (event.m_shiftDown)
+ wParam |= MK_SHIFT;
+ if (event.m_leftDown)
+ wParam |= MK_LBUTTON;
+ if (event.m_middleDown)
+ wParam |= MK_MBUTTON;
+ if (event.m_rightDown)
+ wParam |= MK_RBUTTON;
+ lParam = event.m_x << 16;
+ lParam |= event.m_y;
+
+ if (event.LeftDown())
+ msg = WM_LBUTTONDOWN;
+ else if (event.LeftDClick())
+ msg = WM_LBUTTONDBLCLK;
+ else if (event.LeftUp())
+ msg = WM_LBUTTONUP;
+ else if (event.MiddleDown())
+ msg = WM_MBUTTONDOWN;
+ else if (event.MiddleDClick())
+ msg = WM_MBUTTONDBLCLK;
+ else if (event.MiddleUp())
+ msg = WM_MBUTTONUP;
+ else if (event.RightDown())
+ msg = WM_RBUTTONDOWN;
+ else if (event.RightDClick())
+ msg = WM_RBUTTONDBLCLK;
+ else if (event.RightUp())
+ msg = WM_RBUTTONUP;
+ else if (event.Moving() || event.Dragging())
+ msg = WM_MOUSEMOVE;
+
+ wxString log;
+ if (msg == 0)
+ {
+// wxLogTrace(wxT("no message"));
+ event.Skip(); return;
+ };
+
+ if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam))
+ {
+// wxLogTrace(wxT("msg not delivered"));
+ event.Skip();
+ return;
+ };
+
+// wxLogTrace(wxT("msg sent"));
+}
+
+WXLRESULT wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ if (m_oleObjectHWND == NULL)
+ return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
+
+ switch(nMsg)
+ {
+ case WM_CHAR:
+ case WM_DEADCHAR:
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSCHAR:
+ case WM_SYSDEADCHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ PostMessage(m_oleObjectHWND, nMsg, wParam, lParam);
+
+ default:
+ return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
+ };
+};
+
void wxActiveX::OnSetFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
HRESULT FrameSite::ShowObject()
{
WXOLE_TRACE("IOleClientSite::ShowObject");
+ if (m_window->m_oleObjectHWND)
+ ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
return S_OK;
}
switch (hr)
{
case S_OK:
- return "";
+ return wxEmptyString;
case OLECMDERR_E_UNKNOWNGROUP:
- return "The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.";
+ return wxT("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.");
case OLECMDERR_E_NOTSUPPORTED:
- return "The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.";
+ return wxT("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.");
case OLECMDERR_E_DISABLED:
- return "The command identified by nCmdID is currently disabled and cannot be executed.";
+ return wxT("The command identified by nCmdID is currently disabled and cannot be executed.");
case OLECMDERR_E_NOHELP:
- return "The caller has asked for help on the command identified by nCmdID, but no help is available.";
+ return wxT("The caller has asked for help on the command identified by nCmdID, but no help is available.");
case OLECMDERR_E_CANCELED:
- return "The user canceled the execution of the command.";
+ return wxT("The user canceled the execution of the command.");
case E_INVALIDARG:
- return "E_INVALIDARG";
+ return wxT("E_INVALIDARG");
case E_OUTOFMEMORY:
- return "E_OUTOFMEMORY";
+ return wxT("E_OUTOFMEMORY");
case E_NOINTERFACE:
- return "E_NOINTERFACE";
+ return wxT("E_NOINTERFACE");
case E_UNEXPECTED:
- return "E_UNEXPECTED";
+ return wxT("E_UNEXPECTED");
case STG_E_INVALIDFLAG:
- return "STG_E_INVALIDFLAG";
+ return wxT("STG_E_INVALIDFLAG");
case E_FAIL:
- return "E_FAIL";
+ return wxT("E_FAIL");
case E_NOTIMPL:
- return "E_NOTIMPL";
+ return wxT("E_NOTIMPL");
default:
{
- char buf[64];
- sprintf(buf, "Unknown - 0x%X", hr);
- return wxString(buf);
+ wxString buf;
+ buf.Printf(wxT("Unknown - 0x%X"), hr);
+ return buf;
}
};
};
// construct the table containing all known interfaces
#define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
+ #define ADD_KNOWN_GUID(name) { &name, _T(#name) }
static const KNOWN_IID aKnownIids[] =
{
ADD_KNOWN_IID(Unknown),
ADD_KNOWN_IID(ViewObject),
ADD_KNOWN_IID(ViewObject2),
+ ADD_KNOWN_GUID(IID_IDispatch),
+ ADD_KNOWN_GUID(IID_IWebBrowser),
+ ADD_KNOWN_GUID(IID_IWebBrowserApp),
+ ADD_KNOWN_GUID(IID_IWebBrowser2),
+ ADD_KNOWN_GUID(IID_IWebBrowser),
+ ADD_KNOWN_GUID(DIID_DWebBrowserEvents2),
+ ADD_KNOWN_GUID(DIID_DWebBrowserEvents),
};
// don't clobber preprocessor name space
#undef ADD_KNOWN_IID
+ #undef ADD_KNOWN_GUID
// try to find the interface in the table
for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ )
return s;
}
else
- return "StringFromIID() error";
+ return wxT("StringFromIID() error");
}