]>
Commit | Line | Data |
---|---|---|
c731eb47 RD |
1 | #include "wxActiveX.h" |
2 | #include <wx/strconv.h> | |
83a73288 | 3 | #include <wx/event.h> |
c731eb47 RD |
4 | #include <oleidl.h> |
5 | #include <winerror.h> | |
6 | #include <idispids.h> | |
7 | #include <exdispid.h> | |
8 | #include <olectl.h> | |
9 | #include <Mshtml.h> | |
10 | #include <sstream> | |
11 | using namespace std; | |
12 | ||
13 | // Depending on compilation mode, the wx headers may have undef'd | |
14 | // this, but in this case we need it so the virtual method in | |
15 | // FrameSite will match what is in oleidl.h. | |
16 | #ifndef GetObject | |
17 | #ifdef _UNICODE | |
18 | #define GetObject GetObjectW | |
19 | #else | |
20 | #define GetObject GetObjectA | |
21 | #endif | |
22 | #endif | |
23 | ||
83a73288 | 24 | |
c731eb47 RD |
25 | ////////////////////////////////////////////////////////////////////// |
26 | BEGIN_EVENT_TABLE(wxActiveX, wxWindow) | |
e98fc455 RD |
27 | EVT_SIZE(wxActiveX::OnSize) |
28 | EVT_PAINT(wxActiveX::OnPaint) | |
29 | EVT_MOUSE_EVENTS(wxActiveX::OnMouse) | |
30 | EVT_SET_FOCUS(wxActiveX::OnSetFocus) | |
31 | EVT_KILL_FOCUS(wxActiveX::OnKillFocus) | |
c731eb47 RD |
32 | END_EVENT_TABLE() |
33 | ||
34 | class wxActiveX; | |
35 | ||
1e4a197e | 36 | class FrameSite : |
c731eb47 RD |
37 | public IOleClientSite, |
38 | public IOleInPlaceSiteEx, | |
39 | public IOleInPlaceFrame, | |
40 | public IOleItemContainer, | |
41 | public IDispatch, | |
42 | public IOleCommandTarget, | |
43 | public IOleDocumentSite, | |
44 | public IAdviseSink, | |
45 | public IOleControlSite | |
46 | { | |
47 | private: | |
48 | DECLARE_OLE_UNKNOWN(FrameSite); | |
49 | ||
50 | public: | |
51 | FrameSite(wxActiveX * win); | |
e98fc455 | 52 | virtual ~FrameSite(); |
c731eb47 RD |
53 | |
54 | //IOleWindow | |
55 | STDMETHODIMP GetWindow(HWND*); | |
56 | STDMETHODIMP ContextSensitiveHelp(BOOL); | |
57 | ||
58 | //IOleInPlaceUIWindow | |
59 | STDMETHODIMP GetBorder(LPRECT); | |
60 | STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS); | |
61 | STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS); | |
62 | STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*, LPCOLESTR); | |
1e4a197e | 63 | |
c731eb47 RD |
64 | //IOleInPlaceFrame |
65 | STDMETHODIMP InsertMenus(HMENU, LPOLEMENUGROUPWIDTHS); | |
66 | STDMETHODIMP SetMenu(HMENU, HOLEMENU, HWND); | |
67 | STDMETHODIMP RemoveMenus(HMENU); | |
68 | STDMETHODIMP SetStatusText(LPCOLESTR); | |
69 | STDMETHODIMP EnableModeless(BOOL); | |
70 | STDMETHODIMP TranslateAccelerator(LPMSG, WORD); | |
71 | ||
72 | //IOleInPlaceSite | |
73 | STDMETHODIMP CanInPlaceActivate(); | |
74 | STDMETHODIMP OnInPlaceActivate(); | |
75 | STDMETHODIMP OnUIActivate(); | |
1e4a197e | 76 | STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**, |
c731eb47 RD |
77 | LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO); |
78 | STDMETHODIMP Scroll(SIZE); | |
79 | STDMETHODIMP OnUIDeactivate(BOOL); | |
80 | STDMETHODIMP OnInPlaceDeactivate(); | |
81 | STDMETHODIMP DiscardUndoState(); | |
82 | STDMETHODIMP DeactivateAndUndo(); | |
83 | STDMETHODIMP OnPosRectChange(LPCRECT); | |
84 | ||
85 | //IOleInPlaceSiteEx | |
86 | STDMETHODIMP OnInPlaceActivateEx(BOOL*, DWORD); | |
87 | STDMETHODIMP OnInPlaceDeactivateEx(BOOL); | |
88 | STDMETHODIMP RequestUIActivate(); | |
89 | ||
90 | //IOleClientSite | |
91 | STDMETHODIMP SaveObject(); | |
92 | STDMETHODIMP GetMoniker(DWORD, DWORD, IMoniker**); | |
93 | STDMETHODIMP GetContainer(LPOLECONTAINER FAR*); | |
94 | STDMETHODIMP ShowObject(); | |
95 | STDMETHODIMP OnShowWindow(BOOL); | |
96 | STDMETHODIMP RequestNewObjectLayout(); | |
97 | ||
98 | //IOleControlSite | |
99 | STDMETHODIMP OnControlInfoChanged(); | |
100 | STDMETHODIMP LockInPlaceActive(BOOL); | |
101 | STDMETHODIMP GetExtendedControl(IDispatch**); | |
102 | STDMETHODIMP TransformCoords(POINTL*, POINTF*, DWORD); | |
103 | STDMETHODIMP TranslateAccelerator(LPMSG, DWORD); | |
104 | STDMETHODIMP OnFocus(BOOL); | |
105 | STDMETHODIMP ShowPropertyFrame(); | |
106 | ||
107 | //IOleCommandTarget | |
108 | STDMETHODIMP QueryStatus(const GUID*, ULONG, OLECMD[], OLECMDTEXT*); | |
109 | STDMETHODIMP Exec(const GUID*, DWORD, DWORD, VARIANTARG*, VARIANTARG*); | |
110 | ||
111 | //IParseDisplayName | |
112 | STDMETHODIMP ParseDisplayName(IBindCtx*, LPOLESTR, ULONG*, IMoniker**); | |
113 | ||
114 | //IOleContainer | |
115 | STDMETHODIMP EnumObjects(DWORD, IEnumUnknown**); | |
116 | STDMETHODIMP LockContainer(BOOL); | |
117 | ||
118 | //IOleItemContainer | |
119 | STDMETHODIMP GetObject(LPOLESTR, DWORD, IBindCtx*, REFIID, void**); | |
120 | STDMETHODIMP GetObjectStorage(LPOLESTR, IBindCtx*, REFIID, void**); | |
121 | STDMETHODIMP IsRunning(LPOLESTR); | |
1e4a197e | 122 | |
c731eb47 RD |
123 | //IDispatch |
124 | STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*); | |
125 | STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**); | |
126 | STDMETHODIMP GetTypeInfoCount(unsigned int*); | |
127 | STDMETHODIMP Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*); | |
128 | ||
129 | //IAdviseSink | |
130 | void STDMETHODCALLTYPE OnDataChange(FORMATETC*, STGMEDIUM*); | |
131 | void STDMETHODCALLTYPE OnViewChange(DWORD, LONG); | |
132 | void STDMETHODCALLTYPE OnRename(IMoniker*); | |
133 | void STDMETHODCALLTYPE OnSave(); | |
134 | void STDMETHODCALLTYPE OnClose(); | |
135 | ||
136 | // IOleDocumentSite | |
137 | HRESULT STDMETHODCALLTYPE ActivateMe(IOleDocumentView __RPC_FAR *pViewToActivate); | |
138 | ||
139 | protected: | |
140 | ||
141 | wxActiveX * m_window; | |
142 | ||
143 | HDC m_hDCBuffer; | |
144 | HWND m_hWndParent; | |
145 | ||
146 | bool m_bSupportsWindowlessActivation; | |
147 | bool m_bInPlaceLocked; | |
148 | bool m_bInPlaceActive; | |
149 | bool m_bUIActive; | |
150 | bool m_bWindowless; | |
1e4a197e | 151 | |
c731eb47 RD |
152 | |
153 | ||
154 | LCID m_nAmbientLocale; | |
155 | COLORREF m_clrAmbientForeColor; | |
156 | COLORREF m_clrAmbientBackColor; | |
157 | bool m_bAmbientShowHatching; | |
158 | bool m_bAmbientShowGrabHandles; | |
159 | bool m_bAmbientAppearance; | |
160 | }; | |
161 | ||
162 | DEFINE_OLE_TABLE(FrameSite) | |
163 | OLE_INTERFACE(IID_IUnknown, IOleClientSite) | |
164 | ||
165 | OLE_IINTERFACE(IOleClientSite) | |
166 | ||
167 | OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite) | |
168 | OLE_IINTERFACE(IOleInPlaceSite) | |
169 | OLE_IINTERFACE(IOleInPlaceSiteEx) | |
170 | ||
171 | //OLE_IINTERFACE(IOleWindow) | |
172 | OLE_IINTERFACE(IOleInPlaceUIWindow) | |
173 | OLE_IINTERFACE(IOleInPlaceFrame) | |
174 | ||
175 | OLE_IINTERFACE(IParseDisplayName) | |
176 | OLE_IINTERFACE(IOleContainer) | |
177 | OLE_IINTERFACE(IOleItemContainer) | |
178 | ||
179 | OLE_IINTERFACE(IDispatch) | |
180 | ||
181 | OLE_IINTERFACE(IOleCommandTarget) | |
182 | ||
183 | OLE_IINTERFACE(IOleDocumentSite) | |
184 | ||
185 | OLE_IINTERFACE(IAdviseSink) | |
186 | ||
187 | OLE_IINTERFACE(IOleControlSite) | |
188 | END_OLE_TABLE; | |
189 | ||
190 | ||
d7abf017 | 191 | wxActiveX::wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id, |
83a73288 RD |
192 | const wxPoint& pos, |
193 | const wxSize& size, | |
194 | long style, | |
195 | const wxString& name) : | |
196 | wxWindow(parent, id, pos, size, style, name) | |
c731eb47 | 197 | { |
83a73288 | 198 | m_bAmbientUserMode = true; |
c731eb47 | 199 | m_docAdviseCookie = 0; |
83a73288 | 200 | CreateActiveX(clsid); |
c731eb47 RD |
201 | } |
202 | ||
d7abf017 | 203 | wxActiveX::wxActiveX(wxWindow * parent, wxString progId, wxWindowID id, |
83a73288 RD |
204 | const wxPoint& pos, |
205 | const wxSize& size, | |
206 | long style, | |
207 | const wxString& name) : | |
208 | wxWindow(parent, id, pos, size, style, name) | |
c731eb47 | 209 | { |
83a73288 | 210 | m_bAmbientUserMode = true; |
c731eb47 | 211 | m_docAdviseCookie = 0; |
d3b55102 | 212 | CreateActiveX((LPOLESTR) (const wchar_t *) progId.wc_str(wxConvUTF8)); |
c731eb47 RD |
213 | } |
214 | ||
215 | wxActiveX::~wxActiveX() | |
216 | { | |
217 | // disconnect connection points | |
218 | wxOleConnectionArray::iterator it = m_connections.begin(); | |
219 | while (it != m_connections.end()) | |
220 | { | |
221 | wxOleConnectionPoint& cp = it->first; | |
222 | cp->Unadvise(it->second); | |
223 | ||
224 | it++; | |
225 | }; | |
226 | m_connections.clear(); | |
227 | ||
1e4a197e | 228 | if (m_oleInPlaceObject.Ok()) |
c731eb47 RD |
229 | { |
230 | m_oleInPlaceObject->InPlaceDeactivate(); | |
231 | m_oleInPlaceObject->UIDeactivate(); | |
232 | } | |
233 | ||
234 | ||
1e4a197e | 235 | if (m_oleObject.Ok()) |
c731eb47 RD |
236 | { |
237 | if (m_docAdviseCookie != 0) | |
238 | m_oleObject->Unadvise(m_docAdviseCookie); | |
239 | ||
240 | m_oleObject->DoVerb(OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL); | |
241 | m_oleObject->Close(OLECLOSE_NOSAVE); | |
242 | m_oleObject->SetClientSite(NULL); | |
243 | } | |
244 | } | |
245 | ||
246 | void wxActiveX::CreateActiveX(REFCLSID clsid) | |
247 | { | |
248 | SetTransparent(); | |
249 | ||
250 | HRESULT hret; | |
251 | ||
252 | //////////////////////////////////////////////////////// | |
253 | // FrameSite | |
254 | FrameSite *frame = new FrameSite(this); | |
255 | // oleClientSite | |
256 | hret = m_clientSite.QueryInterface(IID_IOleClientSite, (IDispatch *) frame); | |
257 | wxASSERT(SUCCEEDED(hret)); | |
258 | // adviseSink | |
259 | wxAutoOleInterface<IAdviseSink> adviseSink(IID_IAdviseSink, (IDispatch *) frame); | |
260 | wxASSERT(adviseSink.Ok()); | |
261 | ||
262 | ||
c731eb47 RD |
263 | // // Create Object, get IUnknown interface |
264 | m_ActiveX.CreateInstance(clsid, IID_IUnknown); | |
265 | wxASSERT(m_ActiveX.Ok()); | |
266 | ||
83a73288 RD |
267 | // Type Info |
268 | GetTypeInfo(); | |
269 | ||
c731eb47 | 270 | // Get IOleObject interface |
1e4a197e | 271 | hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); |
c731eb47 | 272 | wxASSERT(SUCCEEDED(hret)); |
d3b55102 | 273 | |
e98fc455 | 274 | // get IViewObject Interface |
1e4a197e | 275 | hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX); |
e98fc455 RD |
276 | wxASSERT(SUCCEEDED(hret)); |
277 | ||
d3b55102 RD |
278 | // document advise |
279 | m_docAdviseCookie = 0; | |
280 | hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie); | |
281 | WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")"); | |
282 | m_oleObject->SetHostNames(L"wxActiveXContainer", NULL); | |
283 | OleSetContainedObject(m_oleObject, TRUE); | |
284 | OleRun(m_oleObject); | |
285 | ||
286 | ||
287 | // Get IOleInPlaceObject interface | |
c731eb47 RD |
288 | hret = m_oleInPlaceObject.QueryInterface(IID_IOleInPlaceObject, m_ActiveX); |
289 | wxASSERT(SUCCEEDED(hret)); | |
290 | ||
291 | // status | |
292 | DWORD dwMiscStatus; | |
293 | m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus); | |
294 | wxASSERT(SUCCEEDED(hret)); | |
295 | ||
296 | // set client site first ? | |
297 | if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) | |
298 | m_oleObject->SetClientSite(m_clientSite); | |
299 | ||
300 | ||
301 | // stream init | |
302 | wxAutoOleInterface<IPersistStreamInit> | |
303 | pPersistStreamInit(IID_IPersistStreamInit, m_oleObject); | |
304 | ||
305 | if (pPersistStreamInit.Ok()) | |
306 | { | |
307 | hret = pPersistStreamInit->InitNew(); | |
308 | WXOLE_WARN(hret, "CreateActiveX::pPersistStreamInit->InitNew()"); | |
309 | }; | |
310 | ||
c731eb47 RD |
311 | if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)) |
312 | m_oleObject->SetClientSite(m_clientSite); | |
313 | ||
314 | ||
315 | int w, h; | |
316 | GetClientSize(&w, &h); | |
317 | RECT posRect; | |
318 | posRect.left = 0; | |
319 | posRect.top = 0; | |
320 | posRect.right = w; | |
321 | posRect.bottom = h; | |
322 | ||
323 | m_oleObjectHWND = 0; | |
d3b55102 RD |
324 | |
325 | if (m_oleInPlaceObject.Ok()) | |
326 | { | |
327 | hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); | |
328 | WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)"); | |
329 | if (SUCCEEDED(hret)) | |
330 | ::SetActiveWindow(m_oleObjectHWND); | |
331 | }; | |
c731eb47 RD |
332 | |
333 | ||
334 | if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)) | |
335 | { | |
d3b55102 | 336 | if (w > 0 && h > 0 && m_oleInPlaceObject.Ok()) |
83a73288 | 337 | m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); |
c731eb47 RD |
338 | |
339 | hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, m_clientSite, 0, (HWND)GetHWND(), &posRect); | |
340 | hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, (HWND)GetHWND(), &posRect); | |
341 | }; | |
342 | ||
d3b55102 | 343 | if (! m_oleObjectHWND && m_oleInPlaceObject.Ok()) |
83a73288 RD |
344 | { |
345 | hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); | |
346 | WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)"); | |
347 | }; | |
348 | ||
349 | if (m_oleObjectHWND) | |
350 | { | |
351 | ::SetActiveWindow(m_oleObjectHWND); | |
352 | ::ShowWindow(m_oleObjectHWND, SW_SHOW); | |
353 | }; | |
c731eb47 RD |
354 | } |
355 | ||
356 | void wxActiveX::CreateActiveX(LPOLESTR progId) | |
357 | { | |
358 | CLSID clsid; | |
359 | if (CLSIDFromProgID(progId, &clsid) != S_OK) | |
360 | return; | |
361 | ||
362 | CreateActiveX(clsid); | |
363 | }; | |
364 | ||
83a73288 RD |
365 | //////////////////////////////////////////////////////////////////////////////////////////////////////////// |
366 | // Case Insensitive Map of Event names to eventTypes | |
367 | // created dynamically at run time in: | |
368 | // EVT_ACTIVEX(eventName, id, fn) | |
369 | // we map the pointer to them so that: | |
370 | // const wxEventType& RegisterActiveXEvent(wxString eventName); | |
371 | // can return a const reference, which is neccessary for event tables | |
372 | // probably should use a wxWindows hash table here, but I'm lazy ... | |
373 | struct less_wxStringI | |
374 | { | |
375 | bool operator()(const wxString& x, const wxString& y) const | |
376 | { | |
377 | return x.CmpNoCase(y) < 0; | |
378 | }; | |
379 | }; | |
380 | ||
e98fc455 RD |
381 | typedef map<wxString, wxEventType *, less_wxStringI> ActiveXNamedEventMap; |
382 | static ActiveXNamedEventMap sg_NamedEventMap; | |
83a73288 | 383 | |
e98fc455 | 384 | const wxEventType& RegisterActiveXEvent(const wxChar *eventName) |
83a73288 | 385 | { |
e98fc455 RD |
386 | wxString ev = eventName; |
387 | ActiveXNamedEventMap::iterator it = sg_NamedEventMap.find(ev); | |
388 | if (it == sg_NamedEventMap.end()) | |
83a73288 | 389 | { |
e98fc455 RD |
390 | wxEventType *et = new wxEventType(wxNewEventType()); |
391 | sg_NamedEventMap[ev] = et; | |
392 | ||
393 | return *et; | |
83a73288 | 394 | }; |
e98fc455 RD |
395 | |
396 | return *(it->second); | |
83a73288 RD |
397 | }; |
398 | ||
83a73288 | 399 | |
e98fc455 RD |
400 | //////////////////////////////////////////////////////////////////////////////////////////////////////////// |
401 | // Map of Event DISPID's to eventTypes | |
402 | // created dynamically at run time in: | |
403 | // EVT_ACTIVEX(eventName, id, fn) | |
404 | // we map the pointer to them so that: | |
405 | // const wxEventType& RegisterActiveXEvent(wxString eventName); | |
406 | // can return a const reference, which is neccessary for event tables | |
407 | ||
408 | typedef map<DISPID, wxEventType *> ActiveXDISPIDEventMap; | |
409 | static ActiveXDISPIDEventMap sg_dispIdEventMap; | |
410 | ||
411 | const wxEventType& RegisterActiveXEvent(DISPID event) | |
83a73288 | 412 | { |
e98fc455 RD |
413 | ActiveXDISPIDEventMap::iterator it = sg_dispIdEventMap.find(event); |
414 | if (it == sg_dispIdEventMap.end()) | |
83a73288 RD |
415 | { |
416 | wxEventType *et = new wxEventType(wxNewEventType()); | |
e98fc455 | 417 | sg_dispIdEventMap[event] = et; |
83a73288 RD |
418 | |
419 | return *et; | |
420 | }; | |
421 | ||
422 | return *(it->second); | |
423 | }; | |
424 | ||
e98fc455 RD |
425 | // one off class for automatic freeing of activeX eventtypes |
426 | class ActiveXEventMapFlusher | |
427 | { | |
428 | public: | |
429 | ~ActiveXEventMapFlusher() | |
430 | { | |
431 | // Named events | |
432 | ActiveXNamedEventMap::iterator it = sg_NamedEventMap.end(); | |
433 | while (it != sg_NamedEventMap.end()) | |
434 | { | |
435 | delete it->second; | |
436 | it++; | |
437 | }; | |
438 | ||
439 | // DISPID events | |
440 | ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.end(); | |
441 | while (dit != sg_dispIdEventMap.end()) | |
442 | { | |
443 | delete dit->second; | |
444 | dit++; | |
445 | }; | |
446 | }; | |
447 | }; | |
448 | ||
449 | static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher; | |
450 | ||
451 | ||
83a73288 RD |
452 | ////////////////////////////////////////////////////// |
453 | bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx) | |
454 | { | |
455 | switch(va.vt) | |
456 | { | |
457 | case VT_VARIANT | VT_BYREF: | |
458 | return MSWVariantToVariant(*va.pvarVal, vx); | |
459 | ||
460 | case VT_I2: | |
461 | case VT_I4: | |
462 | vx = (long) va.iVal; | |
463 | return true; | |
464 | ||
465 | case VT_I2 | VT_BYREF: | |
466 | case VT_I4 | VT_BYREF: | |
467 | vx = (long) *va.piVal; | |
468 | return true; | |
469 | ||
470 | case VT_BSTR: | |
471 | vx = wxString(va.bstrVal); | |
472 | return true; | |
473 | ||
474 | case VT_BSTR | VT_BYREF: | |
475 | vx = wxString(*va.pbstrVal); | |
476 | return true; | |
477 | ||
478 | case VT_BOOL: | |
479 | vx = (va.boolVal != FALSE); | |
480 | return true; | |
481 | ||
482 | case VT_BOOL | VT_BYREF: | |
483 | vx = (*va.pboolVal != FALSE); | |
484 | return true; | |
485 | ||
486 | default: | |
487 | vx.MakeNull(); | |
488 | return false; | |
489 | }; | |
490 | }; | |
491 | ||
492 | bool VariantToMSWVariant(wxVariant& vx, VARIANTARG& va) | |
493 | { | |
494 | switch(va.vt) | |
495 | { | |
496 | case VT_VARIANT | VT_BYREF: | |
497 | return VariantToMSWVariant(vx, va); | |
498 | ||
499 | case VT_I2: | |
500 | case VT_I4: | |
501 | va.iVal = (long) vx; | |
502 | return true; | |
503 | ||
504 | case VT_I2 | VT_BYREF: | |
505 | case VT_I4 | VT_BYREF: | |
506 | *va.piVal = (long) vx; | |
507 | return true; | |
508 | ||
509 | case VT_BOOL: | |
510 | va.boolVal = ((bool) vx) ? TRUE : FALSE; | |
511 | return true; | |
512 | ||
513 | case VT_BOOL | VT_BYREF: | |
514 | *va.pboolVal = ((bool) vx) ? TRUE : FALSE; | |
515 | return true; | |
516 | ||
517 | default: | |
518 | return false; | |
519 | }; | |
520 | }; | |
521 | ||
522 | class wxActiveXEvents : public IDispatch | |
523 | { | |
524 | private: | |
525 | DECLARE_OLE_UNKNOWN(wxActiveXEvents); | |
526 | ||
527 | ||
528 | wxActiveX *m_activeX; | |
529 | ||
530 | public: | |
531 | wxActiveXEvents(wxActiveX *ax) : m_activeX(ax) {} | |
1e4a197e | 532 | virtual ~wxActiveXEvents() |
83a73288 RD |
533 | { |
534 | } | |
535 | ||
536 | //IDispatch | |
537 | STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d) | |
1e4a197e | 538 | { |
83a73288 RD |
539 | return E_NOTIMPL; |
540 | }; | |
541 | ||
542 | STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t) | |
1e4a197e | 543 | { |
83a73288 RD |
544 | return E_NOTIMPL; |
545 | }; | |
546 | ||
547 | STDMETHODIMP GetTypeInfoCount(unsigned int* i) | |
1e4a197e | 548 | { |
83a73288 RD |
549 | return E_NOTIMPL; |
550 | }; | |
551 | ||
552 | ||
e98fc455 RD |
553 | void DispatchEvent(int eventIdx, const wxEventType& eventType, DISPPARAMS * pDispParams) |
554 | { | |
555 | wxASSERT(eventIdx >= 0 && eventIdx < int(m_activeX->m_events.size())); | |
556 | wxActiveX::FuncX &func = m_activeX->m_events[eventIdx]; | |
83a73288 RD |
557 | |
558 | wxActiveXEvent event; | |
559 | event.SetId(m_activeX->GetId()); | |
e98fc455 | 560 | event.SetEventType(eventType); |
83a73288 | 561 | event.m_params.NullList(); |
e98fc455 | 562 | event.m_params.SetName(func.name); |
83a73288 RD |
563 | |
564 | // arguments | |
565 | if (pDispParams) | |
566 | { | |
567 | // cdecl call | |
e98fc455 | 568 | // sometimes the pDispParams does not match the param info for a activex control |
a96fdef3 | 569 | int nArg = wxMin(func.params.size(), pDispParams->cArgs); |
e98fc455 | 570 | for (int i = nArg - 1; i >= 0; i--) |
83a73288 RD |
571 | { |
572 | VARIANTARG& va = pDispParams->rgvarg[i]; | |
e98fc455 | 573 | wxActiveX::ParamX &px = func.params[nArg - i - 1]; |
83a73288 RD |
574 | wxVariant vx; |
575 | ||
83a73288 | 576 | vx.SetName(px.name); |
e98fc455 | 577 | MSWVariantToVariant(va, vx); |
83a73288 RD |
578 | event.m_params.Append(vx); |
579 | }; | |
580 | }; | |
581 | ||
582 | if (func.hasOut) | |
583 | { | |
a96fdef3 | 584 | int nArg = wxMin(func.params.size(), pDispParams->cArgs); |
83a73288 | 585 | m_activeX->GetParent()->ProcessEvent(event); |
e98fc455 | 586 | for (int i = 0; i < nArg; i++) |
83a73288 RD |
587 | { |
588 | VARIANTARG& va = pDispParams->rgvarg[i]; | |
e98fc455 | 589 | wxActiveX::ParamX &px = func.params[nArg - i - 1]; |
83a73288 RD |
590 | |
591 | if (px.IsOut()) | |
592 | { | |
e98fc455 | 593 | wxVariant& vx = event.m_params[nArg - i - 1]; |
1e4a197e | 594 | |
83a73288 RD |
595 | VariantToMSWVariant(vx, va); |
596 | }; | |
597 | }; | |
598 | } | |
599 | else | |
600 | m_activeX->GetParent()->AddPendingEvent(event); | |
601 | ||
e98fc455 RD |
602 | }; |
603 | ||
604 | STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, | |
605 | WORD wFlags, DISPPARAMS * pDispParams, | |
606 | VARIANT * pVarResult, EXCEPINFO * pExcepInfo, | |
607 | unsigned int * puArgErr) | |
1e4a197e | 608 | { |
e98fc455 RD |
609 | if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) |
610 | return E_NOTIMPL; | |
611 | ||
612 | wxASSERT(m_activeX); | |
613 | ||
614 | // map dispid to m_eventsIdx | |
615 | wxActiveX::MemberIdList::iterator mid = m_activeX->m_eventsIdx.find((MEMBERID) dispIdMember); | |
616 | if (mid == m_activeX->m_eventsIdx.end()) | |
617 | return S_OK; | |
618 | ||
1e4a197e | 619 | int funcIdx = mid->second; |
e98fc455 RD |
620 | wxActiveX::FuncX &func = m_activeX->m_events[funcIdx]; |
621 | ||
622 | ||
623 | // try to find dispid event | |
624 | ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.find(dispIdMember); | |
625 | if (dit != sg_dispIdEventMap.end()) | |
626 | { | |
627 | // Dispatch Event | |
628 | DispatchEvent(funcIdx, *(dit->second), pDispParams); | |
629 | return S_OK; | |
630 | }; | |
631 | ||
632 | // try named event | |
633 | ActiveXNamedEventMap::iterator nit = sg_NamedEventMap.find(func.name); | |
634 | if (nit == sg_NamedEventMap.end()) | |
635 | return S_OK; | |
636 | ||
637 | // Dispatch Event | |
638 | DispatchEvent(funcIdx, *(nit->second), pDispParams); | |
83a73288 RD |
639 | return S_OK; |
640 | } | |
641 | }; | |
642 | ||
643 | ||
644 | DEFINE_OLE_TABLE(wxActiveXEvents) | |
645 | OLE_IINTERFACE(IUnknown) | |
646 | OLE_INTERFACE(IID_IDispatch, IDispatch) | |
647 | END_OLE_TABLE; | |
648 | ||
e98fc455 RD |
649 | wxString wxActiveXEvent::EventName() |
650 | { | |
651 | return m_params.GetName(); | |
652 | }; | |
83a73288 RD |
653 | |
654 | int wxActiveXEvent::ParamCount() const | |
655 | { | |
656 | return m_params.GetCount(); | |
657 | }; | |
658 | ||
e98fc455 RD |
659 | wxString wxActiveXEvent::ParamType(int idx) |
660 | { | |
661 | wxASSERT(idx >= 0 && idx < m_params.GetCount()); | |
662 | ||
663 | return m_params[idx].GetType(); | |
664 | }; | |
665 | ||
666 | wxString wxActiveXEvent::ParamName(int idx) | |
667 | { | |
668 | wxASSERT(idx >= 0 && idx < m_params.GetCount()); | |
669 | ||
670 | return m_params[idx].GetName(); | |
671 | }; | |
672 | ||
83a73288 RD |
673 | static wxVariant nullVar; |
674 | ||
675 | wxVariant wxActiveXEvent::operator[] (int idx) const | |
676 | { | |
677 | return (wxVariant&) operator[] (idx); | |
678 | }; | |
679 | ||
680 | wxVariant& wxActiveXEvent::operator[] (int idx) | |
681 | { | |
682 | wxASSERT(idx >= 0 && idx < ParamCount()); | |
683 | ||
684 | return m_params[idx]; | |
685 | }; | |
686 | ||
687 | wxVariant wxActiveXEvent::operator[] (wxString name) const | |
688 | { | |
689 | return (wxVariant&) operator[] (name); | |
690 | }; | |
691 | ||
692 | wxVariant& wxActiveXEvent::operator[] (wxString name) | |
693 | { | |
694 | for (int i = 0; i < m_params.GetCount(); i++) | |
695 | { | |
696 | if (name.CmpNoCase(m_params[i].GetName()) == 0) | |
697 | return m_params[i]; | |
698 | }; | |
699 | ||
1e4a197e RD |
700 | wxString err = wxT("wxActiveXEvent::operator[] invalid name <") + name + wxT(">"); |
701 | err += wxT("\r\nValid Names = :\r\n"); | |
83a73288 RD |
702 | for (i = 0; i < m_params.GetCount(); i++) |
703 | { | |
704 | err += m_params[i].GetName(); | |
1e4a197e | 705 | err += wxT("\r\n"); |
83a73288 RD |
706 | }; |
707 | ||
708 | wxASSERT_MSG(false, err); | |
709 | ||
710 | return nullVar; | |
711 | }; | |
712 | ||
713 | void wxActiveX::GetTypeInfo() | |
714 | { | |
715 | /* | |
1e4a197e | 716 | We are currently only interested in the IDispatch interface |
83a73288 | 717 | to the control. For dual interfaces (TypeKind = TKIND_INTERFACE) |
1e4a197e | 718 | we should drill down through the inheritance |
83a73288 | 719 | (using TYPEATTR->cImplTypes) and GetRefTypeOfImplType(n) |
1e4a197e | 720 | and retrieve all the func names etc that way, then generate a C++ |
83a73288 RD |
721 | header file for it. |
722 | ||
1e4a197e RD |
723 | But we don't do this and probably never will, so if we have a DUAL |
724 | interface then we query for the IDispatch | |
83a73288 RD |
725 | via GetRefTypeOfImplType(-1). |
726 | */ | |
727 | ||
728 | HRESULT hret = 0; | |
729 | ||
730 | // get type info via class info | |
731 | wxAutoOleInterface<IProvideClassInfo> classInfo(IID_IProvideClassInfo, m_ActiveX); | |
732 | if (! classInfo.Ok()) | |
733 | return; | |
734 | ||
735 | // type info | |
736 | wxAutoOleInterface<ITypeInfo> typeInfo; | |
737 | hret = classInfo->GetClassInfo(typeInfo.GetRef()); | |
738 | if (! typeInfo.Ok()) | |
739 | return; | |
740 | ||
741 | // TYPEATTR | |
742 | TYPEATTR *ta = NULL; | |
743 | hret = typeInfo->GetTypeAttr(&ta); | |
744 | if (! ta) | |
745 | return; | |
746 | ||
747 | // this should be a TKIND_COCLASS | |
748 | wxASSERT(ta->typekind == TKIND_COCLASS); | |
749 | ||
750 | // iterate contained interfaces | |
751 | for (int i = 0; i < ta->cImplTypes; i++) | |
752 | { | |
753 | HREFTYPE rt = 0; | |
754 | ||
755 | // get dispatch type info handle | |
756 | hret = typeInfo->GetRefTypeOfImplType(i, &rt); | |
757 | if (! SUCCEEDED(hret)) | |
758 | continue; | |
759 | ||
760 | // get dispatch type info interface | |
761 | wxAutoOleInterface<ITypeInfo> ti; | |
762 | hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef()); | |
763 | if (! ti.Ok()) | |
764 | continue; | |
765 | ||
766 | // check if default event sink | |
767 | bool defEventSink = false; | |
768 | int impTypeFlags = 0; | |
769 | typeInfo->GetImplTypeFlags(i, &impTypeFlags); | |
770 | ||
771 | if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT) | |
772 | { | |
773 | if (impTypeFlags & IMPLTYPEFLAG_FSOURCE) | |
774 | { | |
1e4a197e | 775 | WXOLE_TRACEOUT(wxT("Default Event Sink")); |
83a73288 RD |
776 | defEventSink = true; |
777 | } | |
778 | else | |
779 | { | |
1e4a197e | 780 | WXOLE_TRACEOUT(wxT("Default Interface")); |
83a73288 RD |
781 | } |
782 | }; | |
783 | ||
784 | ||
785 | // process | |
786 | GetTypeInfo(ti, defEventSink); | |
787 | }; | |
788 | ||
789 | ||
790 | // free | |
791 | typeInfo->ReleaseTypeAttr(ta); | |
792 | }; | |
793 | ||
794 | void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink) | |
795 | { | |
796 | ti->AddRef(); | |
797 | wxAutoOleInterface<ITypeInfo> typeInfo(ti); | |
798 | ||
799 | // TYPEATTR | |
800 | TYPEATTR *ta = NULL; | |
801 | HRESULT hret = typeInfo->GetTypeAttr(&ta); | |
802 | if (! ta) | |
803 | return; | |
804 | ||
805 | if (ta->typekind == TKIND_DISPATCH) | |
806 | { | |
1e4a197e | 807 | WXOLE_TRACEOUT(wxT("GUID = ") << GetIIDName(ta->guid).c_str()); |
83a73288 RD |
808 | |
809 | if (defEventSink) | |
810 | { | |
811 | wxActiveXEvents *disp = new wxActiveXEvents(this); | |
812 | ConnectAdvise(ta->guid, disp); | |
813 | }; | |
814 | ||
815 | ||
816 | // Get Function Names | |
817 | for (int i = 0; i < ta->cFuncs; i++) | |
818 | { | |
819 | FUNCDESC FAR *fd = NULL; | |
820 | ||
821 | hret = typeInfo->GetFuncDesc(i, &fd); | |
822 | if (! fd) | |
823 | continue; | |
824 | ||
825 | BSTR anames[1] = {NULL}; | |
826 | unsigned int n = 0; | |
827 | ||
828 | hret = typeInfo->GetNames(fd->memid, anames, 1, &n); | |
829 | ||
830 | if (anames[0]) | |
831 | { | |
832 | wxString name = anames[0]; | |
833 | ||
1e4a197e | 834 | WXOLE_TRACEOUT(wxT("Name ") << i << wxT(" = ") << name.c_str()); |
83a73288 RD |
835 | SysFreeString(anames[0]); |
836 | ||
837 | if (defEventSink) | |
838 | { | |
839 | FuncX func; | |
840 | func.name = name; | |
841 | func.memid = fd->memid; | |
842 | func.hasOut = false; | |
843 | ||
844 | // get Param Names | |
845 | unsigned int maxPNames = fd->cParams + 1; | |
846 | unsigned int nPNames = 0; | |
847 | BSTR *pnames = new BSTR[maxPNames]; | |
848 | ||
849 | hret = typeInfo->GetNames(fd->memid, pnames, maxPNames, &nPNames); | |
e98fc455 | 850 | wxASSERT(int(nPNames) >= fd->cParams + 1); |
83a73288 RD |
851 | |
852 | SysFreeString(pnames[0]); | |
853 | // params | |
854 | for (int p = 0; p < fd->cParams; p++) | |
855 | { | |
856 | ParamX param; | |
e98fc455 | 857 | |
83a73288 RD |
858 | param.flags = fd->lprgelemdescParam[p].idldesc.wIDLFlags; |
859 | param.vt = fd->lprgelemdescParam[p].tdesc.vt; | |
e98fc455 RD |
860 | param.isPtr = (param.vt == VT_PTR); |
861 | param.isSafeArray = (param.vt == VT_SAFEARRAY); | |
862 | if (param.isPtr || param.isSafeArray) | |
863 | param.vt = fd->lprgelemdescParam[p].tdesc.lptdesc->vt; | |
864 | ||
83a73288 RD |
865 | param.name = pnames[p + 1]; |
866 | SysFreeString(pnames[p + 1]); | |
867 | ||
e98fc455 | 868 | func.hasOut |= (param.IsOut() || param.isPtr); |
83a73288 RD |
869 | func.params.push_back(param); |
870 | }; | |
871 | delete [] pnames; | |
872 | ||
873 | m_events.push_back(func); | |
874 | m_eventsIdx[fd->memid] = m_events.size() - 1; | |
875 | }; | |
876 | }; | |
877 | ||
878 | typeInfo->ReleaseFuncDesc(fd); | |
879 | }; | |
880 | } | |
881 | ||
882 | typeInfo->ReleaseTypeAttr(ta); | |
883 | }; | |
884 | ||
e98fc455 RD |
885 | /////////////////////////////////////////////// |
886 | // Type Info exposure | |
887 | const wxActiveX::FuncX& wxActiveX::GetEvent(int idx) const | |
888 | { | |
889 | wxASSERT(idx >= 0 && idx < GetEventCount()); | |
890 | ||
891 | return m_events[idx]; | |
892 | }; | |
893 | ||
894 | /////////////////////////////////////////////// | |
895 | ||
c731eb47 RD |
896 | HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events) |
897 | { | |
898 | wxOleConnectionPoint cp; | |
899 | DWORD adviseCookie = 0; | |
900 | ||
901 | wxAutoOleInterface<IConnectionPointContainer> cpContainer(IID_IConnectionPointContainer, m_ActiveX); | |
902 | if (! cpContainer.Ok()) | |
903 | return E_FAIL; | |
1e4a197e | 904 | |
c731eb47 RD |
905 | HRESULT hret = cpContainer->FindConnectionPoint(riid, cp.GetRef()); |
906 | if (! SUCCEEDED(hret)) | |
907 | return hret; | |
1e4a197e | 908 | |
c731eb47 RD |
909 | hret = cp->Advise(events, &adviseCookie); |
910 | ||
911 | if (SUCCEEDED(hret)) | |
912 | m_connections.push_back(wxOleConnection(cp, adviseCookie)); | |
913 | ||
914 | return hret; | |
915 | }; | |
916 | ||
917 | HRESULT wxActiveX::AmbientPropertyChanged(DISPID dispid) | |
918 | { | |
919 | wxAutoOleInterface<IOleControl> oleControl(IID_IOleControl, m_oleObject); | |
920 | ||
921 | if (oleControl.Ok()) | |
922 | return oleControl->OnAmbientPropertyChange(dispid); | |
923 | else | |
924 | return S_FALSE; | |
925 | }; | |
926 | ||
927 | #define HIMETRIC_PER_INCH 2540 | |
928 | #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) | |
929 | ||
930 | static void PixelsToHimetric(SIZEL &sz) | |
931 | { | |
932 | static int logX = 0; | |
933 | static int logY = 0; | |
934 | ||
935 | if (logY == 0) | |
936 | { | |
937 | // initaliase | |
938 | HDC dc = GetDC(NULL); | |
939 | logX = GetDeviceCaps(dc, LOGPIXELSX); | |
940 | logY = GetDeviceCaps(dc, LOGPIXELSY); | |
941 | ReleaseDC(NULL, dc); | |
942 | }; | |
943 | ||
944 | #define HIMETRIC_INCH 2540 | |
945 | #define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels)) | |
946 | ||
947 | sz.cx = CONVERT(sz.cx, logX); | |
948 | sz.cy = CONVERT(sz.cy, logY); | |
949 | ||
950 | #undef CONVERT | |
951 | #undef HIMETRIC_INCH | |
952 | } | |
953 | ||
954 | ||
955 | void wxActiveX::OnSize(wxSizeEvent& event) | |
956 | { | |
957 | int w, h; | |
958 | GetClientSize(&w, &h); | |
959 | ||
960 | RECT posRect; | |
961 | posRect.left = 0; | |
962 | posRect.top = 0; | |
963 | posRect.right = w; | |
964 | posRect.bottom = h; | |
965 | ||
83a73288 RD |
966 | if (w <= 0 && h <= 0) |
967 | return; | |
968 | ||
c731eb47 | 969 | // extents are in HIMETRIC units |
d3b55102 RD |
970 | if (m_oleObject.Ok()) |
971 | { | |
972 | SIZEL sz = {w, h}; | |
973 | PixelsToHimetric(sz); | |
c731eb47 | 974 | |
d3b55102 RD |
975 | SIZEL sz2; |
976 | ||
977 | m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2); | |
978 | if (sz2.cx != sz.cx || sz.cy != sz2.cy) | |
979 | m_oleObject->SetExtent(DVASPECT_CONTENT, &sz); | |
980 | }; | |
e98fc455 | 981 | |
1e4a197e | 982 | if (m_oleInPlaceObject.Ok()) |
e98fc455 RD |
983 | m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); |
984 | } | |
985 | ||
986 | void wxActiveX::OnPaint(wxPaintEvent& event) | |
987 | { | |
de7b7fe6 | 988 | // wxLogTrace(wxT("repainting activex win")); |
e98fc455 RD |
989 | wxPaintDC dc(this); |
990 | dc.BeginDrawing(); | |
991 | int w, h; | |
992 | GetSize(&w, &h); | |
993 | RECT posRect; | |
994 | posRect.left = 0; | |
995 | posRect.top = 0; | |
996 | posRect.right = w; | |
997 | posRect.bottom = h; | |
998 | ||
999 | // Draw only when control is windowless or deactivated | |
1000 | if (m_viewObject) | |
1001 | { | |
1002 | ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT); | |
1003 | { | |
1004 | RECTL *prcBounds = (RECTL *) &posRect; | |
1e4a197e | 1005 | m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, |
e98fc455 RD |
1006 | (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0); |
1007 | } | |
1008 | } | |
1009 | else | |
1010 | { | |
1011 | dc.SetBrush(*wxRED_BRUSH); | |
1012 | dc.DrawRectangle(0, 0, w, h); | |
1013 | dc.SetBrush(wxNullBrush); | |
1014 | } | |
1015 | dc.EndDrawing(); | |
c731eb47 RD |
1016 | } |
1017 | ||
e98fc455 RD |
1018 | |
1019 | void wxActiveX::OnMouse(wxMouseEvent& event) | |
1020 | { | |
1e4a197e RD |
1021 | if (m_oleObjectHWND == NULL) |
1022 | { | |
de7b7fe6 | 1023 | // wxLogTrace(wxT("no oleInPlaceObject")); |
1e4a197e RD |
1024 | event.Skip(); |
1025 | return; | |
e98fc455 RD |
1026 | } |
1027 | ||
de7b7fe6 | 1028 | // wxLogTrace(wxT("mouse event")); |
e98fc455 RD |
1029 | UINT msg = 0; |
1030 | WPARAM wParam = 0; | |
1031 | LPARAM lParam = 0; | |
1032 | LRESULT lResult = 0; | |
1033 | ||
1e4a197e | 1034 | if (event.m_metaDown) |
e98fc455 | 1035 | wParam |= MK_CONTROL; |
1e4a197e | 1036 | if (event.m_shiftDown) |
e98fc455 | 1037 | wParam |= MK_SHIFT; |
1e4a197e | 1038 | if (event.m_leftDown) |
e98fc455 | 1039 | wParam |= MK_LBUTTON; |
1e4a197e | 1040 | if (event.m_middleDown) |
e98fc455 | 1041 | wParam |= MK_MBUTTON; |
1e4a197e | 1042 | if (event.m_rightDown) |
e98fc455 RD |
1043 | wParam |= MK_RBUTTON; |
1044 | lParam = event.m_x << 16; | |
1045 | lParam |= event.m_y; | |
1046 | ||
1e4a197e | 1047 | if (event.LeftDown()) |
e98fc455 | 1048 | msg = WM_LBUTTONDOWN; |
1e4a197e | 1049 | else if (event.LeftDClick()) |
e98fc455 | 1050 | msg = WM_LBUTTONDBLCLK; |
1e4a197e | 1051 | else if (event.LeftUp()) |
e98fc455 | 1052 | msg = WM_LBUTTONUP; |
1e4a197e | 1053 | else if (event.MiddleDown()) |
e98fc455 | 1054 | msg = WM_MBUTTONDOWN; |
1e4a197e | 1055 | else if (event.MiddleDClick()) |
e98fc455 | 1056 | msg = WM_MBUTTONDBLCLK; |
1e4a197e | 1057 | else if (event.MiddleUp()) |
e98fc455 | 1058 | msg = WM_MBUTTONUP; |
1e4a197e | 1059 | else if (event.RightDown()) |
e98fc455 | 1060 | msg = WM_RBUTTONDOWN; |
1e4a197e | 1061 | else if (event.RightDClick()) |
e98fc455 | 1062 | msg = WM_RBUTTONDBLCLK; |
1e4a197e | 1063 | else if (event.RightUp()) |
e98fc455 | 1064 | msg = WM_RBUTTONUP; |
1e4a197e | 1065 | else if (event.Moving() || event.Dragging()) |
e98fc455 RD |
1066 | msg = WM_MOUSEMOVE; |
1067 | ||
1068 | wxString log; | |
1e4a197e RD |
1069 | if (msg == 0) |
1070 | { | |
de7b7fe6 | 1071 | // wxLogTrace(wxT("no message")); |
1e4a197e | 1072 | event.Skip(); return; |
e98fc455 RD |
1073 | }; |
1074 | ||
1e4a197e RD |
1075 | if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam)) |
1076 | { | |
de7b7fe6 | 1077 | // wxLogTrace(wxT("msg not delivered")); |
1e4a197e RD |
1078 | event.Skip(); |
1079 | return; | |
e98fc455 RD |
1080 | }; |
1081 | ||
de7b7fe6 | 1082 | // wxLogTrace(wxT("msg sent")); |
e98fc455 RD |
1083 | } |
1084 | ||
c140b7e7 | 1085 | WXLRESULT wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) |
e98fc455 RD |
1086 | { |
1087 | if (m_oleObjectHWND == NULL) | |
1088 | return wxWindow::MSWWindowProc(nMsg, wParam, lParam); | |
1089 | ||
1090 | switch(nMsg) | |
1091 | { | |
1092 | case WM_CHAR: | |
1093 | case WM_DEADCHAR: | |
1094 | case WM_KEYDOWN: | |
1095 | case WM_KEYUP: | |
1096 | case WM_SYSCHAR: | |
1097 | case WM_SYSDEADCHAR: | |
1098 | case WM_SYSKEYDOWN: | |
1099 | case WM_SYSKEYUP: | |
1100 | PostMessage(m_oleObjectHWND, nMsg, wParam, lParam); | |
1101 | ||
1102 | default: | |
1103 | return wxWindow::MSWWindowProc(nMsg, wParam, lParam); | |
1104 | }; | |
1105 | }; | |
1106 | ||
c731eb47 RD |
1107 | void wxActiveX::OnSetFocus(wxFocusEvent& event) |
1108 | { | |
1e4a197e | 1109 | if (m_oleInPlaceActiveObject.Ok()) |
c731eb47 RD |
1110 | m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE); |
1111 | } | |
1112 | ||
1113 | void wxActiveX::OnKillFocus(wxFocusEvent& event) | |
1114 | { | |
1e4a197e | 1115 | if (m_oleInPlaceActiveObject.Ok()) |
c731eb47 RD |
1116 | m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE); |
1117 | } | |
1118 | ||
1119 | ||
1120 | FrameSite::FrameSite(wxActiveX * win) | |
1121 | { | |
1122 | m_window = win; | |
1123 | m_bSupportsWindowlessActivation = true; | |
1124 | m_bInPlaceLocked = false; | |
1125 | m_bUIActive = false; | |
1126 | m_bInPlaceActive = false; | |
1127 | m_bWindowless = false; | |
1128 | ||
1129 | m_nAmbientLocale = 0; | |
1130 | m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT); | |
1131 | m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW); | |
1132 | m_bAmbientShowHatching = true; | |
1133 | m_bAmbientShowGrabHandles = true; | |
1134 | m_bAmbientAppearance = true; | |
1e4a197e | 1135 | |
c731eb47 RD |
1136 | m_hDCBuffer = NULL; |
1137 | m_hWndParent = (HWND)m_window->GetHWND(); | |
1138 | } | |
1139 | ||
1140 | FrameSite::~FrameSite() | |
1141 | { | |
1142 | } | |
1143 | ||
1144 | ||
1145 | //IDispatch | |
1146 | ||
1147 | HRESULT FrameSite::GetIDsOfNames(REFIID riid, OLECHAR ** rgszNames, unsigned int cNames, | |
1148 | LCID lcid, DISPID * rgDispId) | |
1149 | { | |
1150 | WXOLE_TRACE("IDispatch::GetIDsOfNames"); | |
1151 | return E_NOTIMPL; | |
1152 | } | |
1153 | ||
1154 | HRESULT FrameSite::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo ** ppTInfo) | |
1155 | { | |
1156 | WXOLE_TRACE("IDispatch::GetTypeInfo"); | |
1157 | return E_NOTIMPL; | |
1158 | } | |
1159 | ||
1160 | HRESULT FrameSite::GetTypeInfoCount(unsigned int * pcTInfo) | |
1161 | { | |
1162 | WXOLE_TRACE("IDispatch::GetTypeInfoCount"); | |
1163 | return E_NOTIMPL; | |
1164 | } | |
1165 | ||
1166 | HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, | |
1167 | WORD wFlags, DISPPARAMS * pDispParams, | |
1168 | VARIANT * pVarResult, EXCEPINFO * pExcepInfo, | |
1169 | unsigned int * puArgErr) | |
1170 | { | |
1171 | WXOLE_TRACE("IDispatch::Invoke"); | |
1172 | ||
1173 | if (!(wFlags & DISPATCH_PROPERTYGET)) | |
1174 | return S_OK; | |
1175 | ||
1176 | HRESULT hr; | |
1177 | ||
1e4a197e | 1178 | if (pVarResult == NULL) |
c731eb47 RD |
1179 | return E_INVALIDARG; |
1180 | ||
1181 | //The most common case is boolean, use as an initial type | |
1182 | V_VT(pVarResult) = VT_BOOL; | |
1183 | ||
1184 | switch (dispIdMember) | |
1185 | { | |
1186 | case DISPID_AMBIENT_MESSAGEREFLECT: | |
1187 | WXOLE_TRACE("Invoke::DISPID_AMBIENT_MESSAGEREFLECT"); | |
1188 | V_BOOL(pVarResult)= FALSE; | |
1189 | return S_OK; | |
1190 | ||
1191 | case DISPID_AMBIENT_DISPLAYASDEFAULT: | |
1192 | WXOLE_TRACE("Invoke::DISPID_AMBIENT_DISPLAYASDEFAULT"); | |
1193 | V_BOOL(pVarResult)= TRUE; | |
1194 | return S_OK; | |
1195 | ||
1196 | case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED: | |
1197 | WXOLE_TRACE("Invoke::DISPID_AMBIENT_OFFLINEIFNOTCONNECTED"); | |
1198 | V_BOOL(pVarResult) = TRUE; | |
1199 | return S_OK; | |
1200 | ||
1201 | ||
1202 | case DISPID_AMBIENT_SILENT: | |
1203 | WXOLE_TRACE("Invoke::DISPID_AMBIENT_SILENT"); | |
1204 | V_BOOL(pVarResult)= TRUE; | |
1205 | return S_OK; | |
1206 | ||
1207 | case DISPID_AMBIENT_APPEARANCE: | |
1208 | pVarResult->vt = VT_BOOL; | |
1209 | pVarResult->boolVal = m_bAmbientAppearance; | |
1210 | break; | |
1211 | ||
1212 | case DISPID_AMBIENT_FORECOLOR: | |
1213 | pVarResult->vt = VT_I4; | |
1214 | pVarResult->lVal = (long) m_clrAmbientForeColor; | |
1215 | break; | |
1216 | ||
1217 | case DISPID_AMBIENT_BACKCOLOR: | |
1218 | pVarResult->vt = VT_I4; | |
1219 | pVarResult->lVal = (long) m_clrAmbientBackColor; | |
1220 | break; | |
1221 | ||
1222 | case DISPID_AMBIENT_LOCALEID: | |
1223 | pVarResult->vt = VT_I4; | |
1224 | pVarResult->lVal = (long) m_nAmbientLocale; | |
1225 | break; | |
1226 | ||
1227 | case DISPID_AMBIENT_USERMODE: | |
1228 | pVarResult->vt = VT_BOOL; | |
1229 | pVarResult->boolVal = m_window->m_bAmbientUserMode; | |
1230 | break; | |
1231 | ||
1232 | case DISPID_AMBIENT_SHOWGRABHANDLES: | |
1233 | pVarResult->vt = VT_BOOL; | |
1234 | pVarResult->boolVal = m_bAmbientShowGrabHandles; | |
1235 | break; | |
1236 | ||
1237 | case DISPID_AMBIENT_SHOWHATCHING: | |
1238 | pVarResult->vt = VT_BOOL; | |
1239 | pVarResult->boolVal = m_bAmbientShowHatching; | |
1240 | break; | |
1241 | ||
1242 | default: | |
1243 | return DISP_E_MEMBERNOTFOUND; | |
1244 | } | |
1245 | ||
1246 | return S_OK; | |
1247 | } | |
1248 | ||
1249 | //IOleWindow | |
1250 | ||
1251 | HRESULT FrameSite::GetWindow(HWND * phwnd) | |
1252 | { | |
1253 | WXOLE_TRACE("IOleWindow::GetWindow"); | |
1e4a197e | 1254 | if (phwnd == NULL) |
c731eb47 RD |
1255 | return E_INVALIDARG; |
1256 | (*phwnd) = m_hWndParent; | |
1257 | return S_OK; | |
1258 | } | |
1259 | ||
1260 | HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode) | |
1261 | { | |
1262 | WXOLE_TRACE("IOleWindow::ContextSensitiveHelp"); | |
1263 | return S_OK; | |
1264 | } | |
1265 | ||
1266 | //IOleInPlaceUIWindow | |
1267 | ||
1268 | HRESULT FrameSite::GetBorder(LPRECT lprectBorder) | |
1269 | { | |
1270 | WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder"); | |
1e4a197e | 1271 | if (lprectBorder == NULL) |
c731eb47 RD |
1272 | return E_INVALIDARG; |
1273 | return INPLACE_E_NOTOOLSPACE; | |
1274 | } | |
1275 | ||
1276 | HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths) | |
1277 | { | |
1278 | WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace"); | |
1e4a197e | 1279 | if (pborderwidths == NULL) |
c731eb47 RD |
1280 | return E_INVALIDARG; |
1281 | return INPLACE_E_NOTOOLSPACE; | |
1282 | } | |
1283 | ||
1284 | HRESULT FrameSite::SetBorderSpace(LPCBORDERWIDTHS pborderwidths) | |
1285 | { | |
1286 | WXOLE_TRACE("IOleInPlaceUIWindow::SetBorderSpace"); | |
1287 | return S_OK; | |
1288 | } | |
1289 | ||
1290 | HRESULT FrameSite::SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) | |
1291 | { | |
1292 | WXOLE_TRACE("IOleInPlaceUIWindow::SetActiveObject"); | |
1293 | ||
1294 | if (pActiveObject) | |
1295 | pActiveObject->AddRef(); | |
1296 | ||
1297 | m_window->m_oleInPlaceActiveObject = pActiveObject; | |
1298 | return S_OK; | |
1299 | } | |
1300 | ||
1301 | //IOleInPlaceFrame | |
1302 | ||
1303 | HRESULT FrameSite::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) | |
1304 | { | |
1305 | WXOLE_TRACE("IOleInPlaceFrame::InsertMenus"); | |
1306 | return S_OK; | |
1307 | } | |
1308 | ||
1309 | HRESULT FrameSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) | |
1310 | { | |
1311 | WXOLE_TRACE("IOleInPlaceFrame::SetMenu"); | |
1312 | return S_OK; | |
1313 | } | |
1314 | ||
1315 | HRESULT FrameSite::RemoveMenus(HMENU hmenuShared) | |
1316 | { | |
1317 | WXOLE_TRACE("IOleInPlaceFrame::RemoveMenus"); | |
1318 | return S_OK; | |
1319 | } | |
1320 | ||
1321 | HRESULT FrameSite::SetStatusText(LPCOLESTR pszStatusText) | |
1322 | { | |
1323 | WXOLE_TRACE("IOleInPlaceFrame::SetStatusText"); | |
1324 | //((wxFrame*)wxGetApp().GetTopWindow())->GetStatusBar()->SetStatusText(pszStatusText); | |
1325 | return S_OK; | |
1326 | } | |
1327 | ||
1328 | HRESULT FrameSite::EnableModeless(BOOL fEnable) | |
1329 | { | |
1330 | WXOLE_TRACE("IOleInPlaceFrame::EnableModeless"); | |
1331 | return S_OK; | |
1332 | } | |
1333 | ||
1334 | HRESULT FrameSite::TranslateAccelerator(LPMSG lpmsg, WORD wID) | |
1335 | { | |
1336 | WXOLE_TRACE("IOleInPlaceFrame::TranslateAccelerator"); | |
1337 | // TODO: send an event with this id | |
1338 | if (m_window->m_oleInPlaceActiveObject.Ok()) | |
1339 | m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg); | |
1340 | ||
1341 | return S_FALSE; | |
1342 | } | |
1343 | ||
1344 | //IOleInPlaceSite | |
1345 | ||
1346 | HRESULT FrameSite::CanInPlaceActivate() | |
1347 | { | |
1348 | WXOLE_TRACE("IOleInPlaceSite::CanInPlaceActivate"); | |
1349 | return S_OK; | |
1350 | } | |
1351 | ||
1352 | HRESULT FrameSite::OnInPlaceActivate() | |
1353 | { | |
1354 | WXOLE_TRACE("IOleInPlaceSite::OnInPlaceActivate"); | |
1355 | m_bInPlaceActive = true; | |
1356 | return S_OK; | |
1357 | } | |
1358 | ||
1359 | HRESULT FrameSite::OnUIActivate() | |
1360 | { | |
1361 | WXOLE_TRACE("IOleInPlaceSite::OnUIActivate"); | |
1362 | m_bUIActive = true; | |
1363 | return S_OK; | |
1364 | } | |
1365 | ||
1366 | HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame, | |
1367 | IOleInPlaceUIWindow **ppDoc, | |
1368 | LPRECT lprcPosRect, | |
1369 | LPRECT lprcClipRect, | |
1370 | LPOLEINPLACEFRAMEINFO lpFrameInfo) | |
1371 | { | |
1372 | WXOLE_TRACE("IOleInPlaceSite::GetWindowContext"); | |
1373 | if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || | |
1374 | lprcClipRect == NULL || lpFrameInfo == NULL) | |
1375 | { | |
1e4a197e | 1376 | if (ppFrame != NULL) |
c731eb47 | 1377 | (*ppFrame) = NULL; |
1e4a197e | 1378 | if (ppDoc != NULL) |
c731eb47 RD |
1379 | (*ppDoc) = NULL; |
1380 | return E_INVALIDARG; | |
1381 | } | |
1382 | ||
1383 | HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame); | |
1384 | if (! SUCCEEDED(hr)) | |
1385 | { | |
1386 | WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceFrame Error !"); | |
1387 | return E_UNEXPECTED; | |
1388 | }; | |
1389 | ||
1390 | hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc); | |
1391 | if (! SUCCEEDED(hr)) | |
1392 | { | |
1393 | WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceUIWindow Error !"); | |
1394 | (*ppFrame)->Release(); | |
1395 | *ppFrame = NULL; | |
1396 | return E_UNEXPECTED; | |
1397 | }; | |
1398 | ||
1399 | int w, h; | |
1400 | m_window->GetClientSize(&w, &h); | |
1401 | if (lprcPosRect) | |
1402 | { | |
1403 | lprcPosRect->left = lprcPosRect->top = 0; | |
1404 | lprcPosRect->right = w; | |
1405 | lprcPosRect->bottom = h; | |
1406 | }; | |
1407 | if (lprcClipRect) | |
1408 | { | |
1409 | lprcClipRect->left = lprcClipRect->top = 0; | |
1410 | lprcClipRect->right = w; | |
1411 | lprcClipRect->bottom = h; | |
1412 | }; | |
1413 | ||
1414 | memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO)); | |
1415 | lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO); | |
1416 | lpFrameInfo->hwndFrame = m_hWndParent; | |
1417 | ||
1418 | return S_OK; | |
1419 | } | |
1420 | ||
1421 | HRESULT FrameSite::Scroll(SIZE scrollExtent) | |
1422 | { | |
1423 | WXOLE_TRACE("IOleInPlaceSite::Scroll"); | |
1424 | return S_OK; | |
1425 | } | |
1426 | ||
1427 | HRESULT FrameSite::OnUIDeactivate(BOOL fUndoable) | |
1428 | { | |
1429 | WXOLE_TRACE("IOleInPlaceSite::OnUIDeactivate"); | |
1430 | m_bUIActive = false; | |
1431 | return S_OK; | |
1432 | } | |
1433 | ||
1434 | HRESULT FrameSite::OnInPlaceDeactivate() | |
1435 | { | |
1436 | WXOLE_TRACE("IOleInPlaceSite::OnInPlaceDeactivate"); | |
1437 | m_bInPlaceActive = false; | |
1438 | return S_OK; | |
1439 | } | |
1440 | ||
1441 | HRESULT FrameSite::DiscardUndoState() | |
1442 | { | |
1443 | WXOLE_TRACE("IOleInPlaceSite::DiscardUndoState"); | |
1444 | return S_OK; | |
1445 | } | |
1446 | ||
1447 | HRESULT FrameSite::DeactivateAndUndo() | |
1448 | { | |
1449 | WXOLE_TRACE("IOleInPlaceSite::DeactivateAndUndo"); | |
1450 | return S_OK; | |
1451 | } | |
1452 | ||
1453 | HRESULT FrameSite::OnPosRectChange(LPCRECT lprcPosRect) | |
1454 | { | |
1455 | WXOLE_TRACE("IOleInPlaceSite::OnPosRectChange"); | |
1456 | if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect) | |
1457 | m_window->m_oleInPlaceObject->SetObjectRects(lprcPosRect, lprcPosRect); | |
1458 | ||
1459 | return S_OK; | |
1460 | } | |
1461 | ||
1462 | //IOleInPlaceSiteEx | |
1463 | ||
1464 | HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags) | |
1465 | { | |
1466 | WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx"); | |
1467 | OleLockRunning(m_window->m_ActiveX, TRUE, FALSE); | |
1e4a197e | 1468 | if (pfNoRedraw) |
c731eb47 RD |
1469 | (*pfNoRedraw) = FALSE; |
1470 | return S_OK; | |
1471 | } | |
1472 | ||
1473 | HRESULT FrameSite::OnInPlaceDeactivateEx(BOOL fNoRedraw) | |
1474 | { | |
1475 | WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceDeactivateEx"); | |
1476 | OleLockRunning(m_window->m_ActiveX, FALSE, FALSE); | |
1477 | return S_OK; | |
1478 | } | |
1479 | ||
1480 | HRESULT FrameSite::RequestUIActivate() | |
1481 | { | |
1482 | WXOLE_TRACE("IOleInPlaceSiteEx::RequestUIActivate"); | |
1483 | return S_OK; | |
1484 | } | |
1485 | ||
1486 | ||
1487 | //IOleClientSite | |
1488 | ||
1489 | HRESULT FrameSite::SaveObject() | |
1490 | { | |
1491 | WXOLE_TRACE("IOleClientSite::SaveObject"); | |
1492 | return S_OK; | |
1493 | } | |
1494 | ||
1495 | HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, | |
1496 | IMoniker ** ppmk) | |
1497 | { | |
1498 | WXOLE_TRACE("IOleClientSite::GetMoniker"); | |
1499 | return E_NOTIMPL; | |
1500 | } | |
1501 | ||
1502 | HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer) | |
1503 | { | |
1504 | WXOLE_TRACE("IOleClientSite::GetContainer"); | |
1e4a197e | 1505 | if (ppContainer == NULL) |
c731eb47 | 1506 | return E_INVALIDARG; |
1e4a197e | 1507 | |
c731eb47 RD |
1508 | HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer)); |
1509 | wxASSERT(SUCCEEDED(hr)); | |
1510 | ||
1511 | return hr; | |
1512 | } | |
1513 | ||
1514 | HRESULT FrameSite::ShowObject() | |
1515 | { | |
1516 | WXOLE_TRACE("IOleClientSite::ShowObject"); | |
83a73288 RD |
1517 | if (m_window->m_oleObjectHWND) |
1518 | ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW); | |
c731eb47 RD |
1519 | return S_OK; |
1520 | } | |
1521 | ||
1522 | HRESULT FrameSite::OnShowWindow(BOOL fShow) | |
1523 | { | |
1524 | WXOLE_TRACE("IOleClientSite::OnShowWindow"); | |
1525 | return S_OK; | |
1526 | } | |
1527 | ||
1528 | HRESULT FrameSite::RequestNewObjectLayout() | |
1529 | { | |
1530 | WXOLE_TRACE("IOleClientSite::RequestNewObjectLayout"); | |
1531 | return E_NOTIMPL; | |
1532 | } | |
1533 | ||
1534 | // IParseDisplayName | |
1535 | ||
1536 | HRESULT FrameSite::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, | |
1537 | ULONG *pchEaten, IMoniker **ppmkOut) | |
1538 | { | |
1539 | WXOLE_TRACE("IParseDisplayName::ParseDisplayName"); | |
1540 | return E_NOTIMPL; | |
1541 | } | |
1542 | ||
1543 | //IOleContainer | |
1544 | ||
1545 | HRESULT FrameSite::EnumObjects(DWORD grfFlags, IEnumUnknown **ppenum) | |
1546 | { | |
1547 | WXOLE_TRACE("IOleContainer::EnumObjects"); | |
1548 | return E_NOTIMPL; | |
1549 | } | |
1550 | ||
1551 | HRESULT FrameSite::LockContainer(BOOL fLock) | |
1552 | { | |
1553 | WXOLE_TRACE("IOleContainer::LockContainer"); | |
1554 | // TODO | |
1555 | return S_OK; | |
1556 | } | |
1557 | ||
1558 | //IOleItemContainer | |
1559 | ||
1e4a197e | 1560 | HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded, |
c731eb47 RD |
1561 | IBindCtx * pbc, REFIID riid, void ** ppvObject) |
1562 | { | |
1563 | WXOLE_TRACE("IOleItemContainer::GetObject"); | |
1e4a197e | 1564 | if (pszItem == NULL) |
c731eb47 | 1565 | return E_INVALIDARG; |
1e4a197e | 1566 | if (ppvObject == NULL) |
c731eb47 RD |
1567 | return E_INVALIDARG; |
1568 | ||
1569 | *ppvObject = NULL; | |
1570 | return MK_E_NOOBJECT; | |
1571 | } | |
1572 | ||
1e4a197e | 1573 | HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc, |
c731eb47 RD |
1574 | REFIID riid, void ** ppvStorage) |
1575 | { | |
1576 | WXOLE_TRACE("IOleItemContainer::GetObjectStorage"); | |
1e4a197e | 1577 | if (pszItem == NULL) |
c731eb47 | 1578 | return E_INVALIDARG; |
1e4a197e | 1579 | if (ppvStorage == NULL) |
c731eb47 RD |
1580 | return E_INVALIDARG; |
1581 | ||
1582 | *ppvStorage = NULL; | |
1583 | return MK_E_NOOBJECT; | |
1584 | } | |
1585 | ||
1586 | HRESULT FrameSite::IsRunning(LPOLESTR pszItem) | |
1587 | { | |
1588 | WXOLE_TRACE("IOleItemContainer::IsRunning"); | |
1e4a197e | 1589 | if (pszItem == NULL) |
c731eb47 RD |
1590 | return E_INVALIDARG; |
1591 | ||
1592 | return MK_E_NOOBJECT; | |
1593 | } | |
1594 | ||
1595 | ||
1596 | ||
1597 | //IOleControlSite | |
1598 | ||
1599 | HRESULT FrameSite::OnControlInfoChanged() | |
1600 | { | |
1601 | WXOLE_TRACE("IOleControlSite::OnControlInfoChanged"); | |
1602 | return S_OK; | |
1603 | } | |
1604 | ||
1605 | HRESULT FrameSite::LockInPlaceActive(BOOL fLock) | |
1606 | { | |
1607 | WXOLE_TRACE("IOleControlSite::LockInPlaceActive"); | |
1608 | m_bInPlaceLocked = (fLock) ? true : false; | |
1609 | return S_OK; | |
1610 | } | |
1611 | ||
1612 | HRESULT FrameSite::GetExtendedControl(IDispatch ** ppDisp) | |
1613 | { | |
1614 | WXOLE_TRACE("IOleControlSite::GetExtendedControl"); | |
1615 | return E_NOTIMPL; | |
1616 | } | |
1617 | ||
1618 | HRESULT FrameSite::TransformCoords(POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD dwFlags) | |
1619 | { | |
1620 | WXOLE_TRACE("IOleControlSite::TransformCoords"); | |
1621 | HRESULT hr = S_OK; | |
1622 | ||
1623 | if (pPtlHimetric == NULL) | |
1624 | return E_INVALIDARG; | |
1625 | ||
1626 | if (pPtfContainer == NULL) | |
1627 | return E_INVALIDARG; | |
1628 | ||
1629 | return E_NOTIMPL; | |
1630 | ||
1631 | } | |
1632 | ||
1633 | HRESULT FrameSite::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers) | |
1634 | { | |
1635 | WXOLE_TRACE("IOleControlSite::TranslateAccelerator"); | |
1636 | // TODO: send an event with this id | |
1637 | return E_NOTIMPL; | |
1638 | } | |
1639 | ||
1640 | HRESULT FrameSite::OnFocus(BOOL fGotFocus) | |
1641 | { | |
1642 | WXOLE_TRACE("IOleControlSite::OnFocus"); | |
1643 | return S_OK; | |
1644 | } | |
1645 | ||
1646 | HRESULT FrameSite::ShowPropertyFrame() | |
1647 | { | |
1648 | WXOLE_TRACE("IOleControlSite::ShowPropertyFrame"); | |
1649 | return E_NOTIMPL; | |
1650 | } | |
1651 | ||
1652 | //IOleCommandTarget | |
1653 | ||
1e4a197e | 1654 | HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, |
c731eb47 RD |
1655 | OLECMD * prgCmds, OLECMDTEXT * pCmdTet) |
1656 | { | |
1657 | WXOLE_TRACE("IOleCommandTarget::QueryStatus"); | |
1658 | if (prgCmds == NULL) return E_INVALIDARG; | |
1659 | bool bCmdGroupFound = false; | |
1660 | ||
1661 | for (ULONG nCmd = 0; nCmd < cCmds; nCmd++) | |
1662 | { | |
1663 | // unsupported by default | |
1664 | prgCmds[nCmd].cmdf = 0; | |
1665 | ||
1666 | // TODO | |
1667 | } | |
1668 | ||
1669 | if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; } | |
1670 | return S_OK; | |
1671 | } | |
1672 | ||
1e4a197e RD |
1673 | HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, |
1674 | DWORD nCmdExecOpt, VARIANTARG * pVaIn, | |
c731eb47 RD |
1675 | VARIANTARG * pVaOut) |
1676 | { | |
1677 | WXOLE_TRACE("IOleCommandTarget::Exec"); | |
1678 | bool bCmdGroupFound = false; | |
1679 | ||
1680 | if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; } | |
1681 | return OLECMDERR_E_NOTSUPPORTED; | |
1682 | } | |
1683 | ||
1684 | //IAdviseSink | |
1685 | ||
1686 | void STDMETHODCALLTYPE FrameSite::OnDataChange(FORMATETC * pFormatEtc, STGMEDIUM * pgStgMed) | |
1687 | { | |
1688 | WXOLE_TRACE("IAdviseSink::OnDataChange"); | |
1689 | } | |
1690 | ||
1691 | void STDMETHODCALLTYPE FrameSite::OnViewChange(DWORD dwAspect, LONG lIndex) | |
1692 | { | |
1693 | WXOLE_TRACE("IAdviseSink::OnViewChange"); | |
1694 | // redraw the control | |
1695 | } | |
1696 | ||
1697 | void STDMETHODCALLTYPE FrameSite::OnRename(IMoniker * pmk) | |
1698 | { | |
1699 | WXOLE_TRACE("IAdviseSink::OnRename"); | |
1700 | } | |
1701 | ||
1702 | void STDMETHODCALLTYPE FrameSite::OnSave() | |
1703 | { | |
1704 | WXOLE_TRACE("IAdviseSink::OnSave"); | |
1705 | } | |
1706 | ||
1707 | void STDMETHODCALLTYPE FrameSite::OnClose() | |
1708 | { | |
1709 | WXOLE_TRACE("IAdviseSink::OnClose"); | |
1710 | } | |
1711 | ||
1712 | ///////////////////////////////////////////// | |
1713 | // IOleDocumentSite | |
1714 | HRESULT STDMETHODCALLTYPE FrameSite::ActivateMe( | |
1715 | /* [in] */ IOleDocumentView __RPC_FAR *pViewToActivate) | |
1716 | { | |
1717 | wxAutoOleInterface<IOleInPlaceSite> inPlaceSite(IID_IOleInPlaceSite, (IDispatch *) this); | |
1718 | if (!inPlaceSite.Ok()) | |
1719 | return E_FAIL; | |
1720 | ||
1721 | if (pViewToActivate) | |
1722 | { | |
1723 | m_window->m_docView = pViewToActivate; | |
1724 | m_window->m_docView->SetInPlaceSite(inPlaceSite); | |
1725 | } | |
1726 | else | |
1727 | { | |
1728 | wxAutoOleInterface<IOleDocument> oleDoc(IID_IOleDocument, m_window->m_oleObject); | |
1729 | if (! oleDoc.Ok()) | |
1730 | return E_FAIL; | |
1731 | ||
1732 | HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, 0, m_window->m_docView.GetRef()); | |
1733 | if (hr != S_OK) | |
1734 | return E_FAIL; | |
1735 | ||
1736 | m_window->m_docView->SetInPlaceSite(inPlaceSite); | |
1737 | }; | |
1738 | ||
1739 | m_window->m_docView->UIActivate(TRUE); | |
1740 | ||
1741 | return S_OK; | |
1742 | }; | |
1743 | ||
1744 | ||
1745 | ||
1746 | static IMalloc *iMalloc = NULL; | |
1747 | ||
1748 | IMalloc *wxOleInit::GetIMalloc() | |
1749 | { | |
1750 | assert(iMalloc); | |
1751 | return iMalloc; | |
1752 | }; | |
1753 | ||
1754 | wxOleInit::wxOleInit() | |
1755 | { | |
1756 | if (OleInitialize(NULL) == S_OK && iMalloc == NULL) | |
1757 | CoGetMalloc(1, &iMalloc); | |
1758 | else if (iMalloc) | |
1759 | iMalloc->AddRef(); | |
1760 | }; | |
1761 | ||
1762 | wxOleInit::~wxOleInit() | |
1763 | { | |
1764 | if (iMalloc) | |
1765 | { | |
1766 | if (iMalloc->Release() == 0) | |
1767 | iMalloc = NULL; | |
1768 | }; | |
1769 | ||
1770 | OleUninitialize(); | |
1771 | } | |
1772 | ||
1773 | wxString OLEHResultToString(HRESULT hr) | |
1774 | { | |
1775 | switch (hr) | |
1776 | { | |
1777 | case S_OK: | |
1e4a197e | 1778 | return wxEmptyString; |
c731eb47 RD |
1779 | |
1780 | case OLECMDERR_E_UNKNOWNGROUP: | |
1e4a197e | 1781 | return wxT("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group."); |
c731eb47 RD |
1782 | |
1783 | case OLECMDERR_E_NOTSUPPORTED: | |
1e4a197e | 1784 | return wxT("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup."); |
c731eb47 RD |
1785 | |
1786 | case OLECMDERR_E_DISABLED: | |
1e4a197e | 1787 | return wxT("The command identified by nCmdID is currently disabled and cannot be executed."); |
c731eb47 RD |
1788 | |
1789 | case OLECMDERR_E_NOHELP: | |
1e4a197e | 1790 | return wxT("The caller has asked for help on the command identified by nCmdID, but no help is available."); |
c731eb47 RD |
1791 | |
1792 | case OLECMDERR_E_CANCELED: | |
1e4a197e | 1793 | return wxT("The user canceled the execution of the command."); |
c731eb47 RD |
1794 | |
1795 | case E_INVALIDARG: | |
1e4a197e | 1796 | return wxT("E_INVALIDARG"); |
c731eb47 RD |
1797 | |
1798 | case E_OUTOFMEMORY: | |
1e4a197e | 1799 | return wxT("E_OUTOFMEMORY"); |
c731eb47 RD |
1800 | |
1801 | case E_NOINTERFACE: | |
1e4a197e | 1802 | return wxT("E_NOINTERFACE"); |
c731eb47 RD |
1803 | |
1804 | case E_UNEXPECTED: | |
1e4a197e | 1805 | return wxT("E_UNEXPECTED"); |
c731eb47 RD |
1806 | |
1807 | case STG_E_INVALIDFLAG: | |
1e4a197e | 1808 | return wxT("STG_E_INVALIDFLAG"); |
c731eb47 RD |
1809 | |
1810 | case E_FAIL: | |
1e4a197e | 1811 | return wxT("E_FAIL"); |
c731eb47 RD |
1812 | |
1813 | case E_NOTIMPL: | |
1e4a197e | 1814 | return wxT("E_NOTIMPL"); |
c731eb47 RD |
1815 | |
1816 | default: | |
1817 | { | |
1e4a197e RD |
1818 | wxString buf; |
1819 | buf.Printf(wxT("Unknown - 0x%X"), hr); | |
1820 | return buf; | |
c731eb47 RD |
1821 | } |
1822 | }; | |
1823 | }; | |
1824 | ||
1825 | // borrowed from src/msw/ole/oleutils.cpp | |
1826 | wxString GetIIDName(REFIID riid) | |
1827 | { | |
1828 | // an association between symbolic name and numeric value of an IID | |
1e4a197e | 1829 | struct KNOWN_IID |
c731eb47 RD |
1830 | { |
1831 | const IID *pIid; | |
1832 | const wxChar *szName; | |
1833 | }; | |
1834 | ||
1835 | // construct the table containing all known interfaces | |
1836 | #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) } | |
83a73288 | 1837 | #define ADD_KNOWN_GUID(name) { &name, _T(#name) } |
c731eb47 | 1838 | |
1e4a197e | 1839 | static const KNOWN_IID aKnownIids[] = |
c731eb47 RD |
1840 | { |
1841 | ADD_KNOWN_IID(AdviseSink), | |
1842 | ADD_KNOWN_IID(AdviseSink2), | |
1843 | ADD_KNOWN_IID(BindCtx), | |
1844 | ADD_KNOWN_IID(ClassFactory), | |
1845 | #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__) | |
1846 | ADD_KNOWN_IID(ContinueCallback), | |
1847 | ADD_KNOWN_IID(EnumOleDocumentViews), | |
1848 | ADD_KNOWN_IID(OleCommandTarget), | |
1849 | ADD_KNOWN_IID(OleDocument), | |
1850 | ADD_KNOWN_IID(OleDocumentSite), | |
1851 | ADD_KNOWN_IID(OleDocumentView), | |
1852 | ADD_KNOWN_IID(Print), | |
1853 | #endif | |
1854 | ADD_KNOWN_IID(DataAdviseHolder), | |
1855 | ADD_KNOWN_IID(DataObject), | |
1856 | ADD_KNOWN_IID(Debug), | |
1857 | ADD_KNOWN_IID(DebugStream), | |
1858 | ADD_KNOWN_IID(DfReserved1), | |
1859 | ADD_KNOWN_IID(DfReserved2), | |
1860 | ADD_KNOWN_IID(DfReserved3), | |
1861 | ADD_KNOWN_IID(Dispatch), | |
1862 | ADD_KNOWN_IID(DropSource), | |
1863 | ADD_KNOWN_IID(DropTarget), | |
1864 | ADD_KNOWN_IID(EnumCallback), | |
1865 | ADD_KNOWN_IID(EnumFORMATETC), | |
1866 | ADD_KNOWN_IID(EnumGeneric), | |
1867 | ADD_KNOWN_IID(EnumHolder), | |
1868 | ADD_KNOWN_IID(EnumMoniker), | |
1869 | ADD_KNOWN_IID(EnumOLEVERB), | |
1870 | ADD_KNOWN_IID(EnumSTATDATA), | |
1871 | ADD_KNOWN_IID(EnumSTATSTG), | |
1872 | ADD_KNOWN_IID(EnumString), | |
1873 | ADD_KNOWN_IID(EnumUnknown), | |
1874 | ADD_KNOWN_IID(EnumVARIANT), | |
1875 | ADD_KNOWN_IID(ExternalConnection), | |
1876 | ADD_KNOWN_IID(InternalMoniker), | |
1877 | ADD_KNOWN_IID(LockBytes), | |
1878 | ADD_KNOWN_IID(Malloc), | |
1879 | ADD_KNOWN_IID(Marshal), | |
1880 | ADD_KNOWN_IID(MessageFilter), | |
1881 | ADD_KNOWN_IID(Moniker), | |
1882 | ADD_KNOWN_IID(OleAdviseHolder), | |
1883 | ADD_KNOWN_IID(OleCache), | |
1884 | ADD_KNOWN_IID(OleCache2), | |
1885 | ADD_KNOWN_IID(OleCacheControl), | |
1886 | ADD_KNOWN_IID(OleClientSite), | |
1887 | ADD_KNOWN_IID(OleContainer), | |
1888 | ADD_KNOWN_IID(OleInPlaceActiveObject), | |
1889 | ADD_KNOWN_IID(OleInPlaceFrame), | |
1890 | ADD_KNOWN_IID(OleInPlaceObject), | |
1891 | ADD_KNOWN_IID(OleInPlaceSite), | |
1892 | ADD_KNOWN_IID(OleInPlaceUIWindow), | |
1893 | ADD_KNOWN_IID(OleItemContainer), | |
1894 | ADD_KNOWN_IID(OleLink), | |
1895 | ADD_KNOWN_IID(OleManager), | |
1896 | ADD_KNOWN_IID(OleObject), | |
1897 | ADD_KNOWN_IID(OlePresObj), | |
1898 | ADD_KNOWN_IID(OleWindow), | |
1899 | ADD_KNOWN_IID(PSFactory), | |
1900 | ADD_KNOWN_IID(ParseDisplayName), | |
1901 | ADD_KNOWN_IID(Persist), | |
1902 | ADD_KNOWN_IID(PersistFile), | |
1903 | ADD_KNOWN_IID(PersistStorage), | |
1904 | ADD_KNOWN_IID(PersistStream), | |
1905 | ADD_KNOWN_IID(ProxyManager), | |
1906 | ADD_KNOWN_IID(RootStorage), | |
1907 | ADD_KNOWN_IID(RpcChannel), | |
1908 | ADD_KNOWN_IID(RpcProxy), | |
1909 | ADD_KNOWN_IID(RpcStub), | |
1910 | ADD_KNOWN_IID(RunnableObject), | |
1911 | ADD_KNOWN_IID(RunningObjectTable), | |
1912 | ADD_KNOWN_IID(StdMarshalInfo), | |
1913 | ADD_KNOWN_IID(Storage), | |
1914 | ADD_KNOWN_IID(Stream), | |
1915 | ADD_KNOWN_IID(StubManager), | |
1916 | ADD_KNOWN_IID(Unknown), | |
1917 | ADD_KNOWN_IID(ViewObject), | |
1918 | ADD_KNOWN_IID(ViewObject2), | |
83a73288 RD |
1919 | ADD_KNOWN_GUID(IID_IDispatch), |
1920 | ADD_KNOWN_GUID(IID_IWebBrowser), | |
1921 | ADD_KNOWN_GUID(IID_IWebBrowserApp), | |
1922 | ADD_KNOWN_GUID(IID_IWebBrowser2), | |
1923 | ADD_KNOWN_GUID(IID_IWebBrowser), | |
1924 | ADD_KNOWN_GUID(DIID_DWebBrowserEvents2), | |
1925 | ADD_KNOWN_GUID(DIID_DWebBrowserEvents), | |
c731eb47 RD |
1926 | }; |
1927 | ||
1928 | // don't clobber preprocessor name space | |
1929 | #undef ADD_KNOWN_IID | |
83a73288 | 1930 | #undef ADD_KNOWN_GUID |
c731eb47 RD |
1931 | |
1932 | // try to find the interface in the table | |
1e4a197e | 1933 | for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ ) |
c731eb47 | 1934 | { |
1e4a197e | 1935 | if ( riid == *aKnownIids[ui].pIid ) |
c731eb47 RD |
1936 | { |
1937 | return aKnownIids[ui].szName; | |
1938 | } | |
1939 | } | |
1940 | ||
1941 | // unknown IID, just transform to string | |
1942 | LPOLESTR str = NULL; | |
1943 | StringFromIID(riid, &str); | |
1944 | if (str) | |
1945 | { | |
1946 | wxString s = str; | |
1947 | CoTaskMemFree(str); | |
1948 | return s; | |
1949 | } | |
1950 | else | |
1e4a197e | 1951 | return wxT("StringFromIID() error"); |
c731eb47 | 1952 | } |