1 /*******************************************************************************
2 * Copyright (c) 2000, 2017 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.browser;
18 import org.eclipse.swt.*;
19 import org.eclipse.swt.internal.*;
20 import org.eclipse.swt.internal.ole.win32.*;
21 import org.eclipse.swt.internal.win32.*;
22 import org.eclipse.swt.ole.win32.*;
23 import org.eclipse.swt.widgets.*;
25 class WebSite extends OleControlSite {
26 COMObject iDocHostUIHandler;
27 COMObject iDocHostShowUI;
28 COMObject iServiceProvider;
29 COMObject iInternetSecurityManager;
30 COMObject iOleCommandTarget;
31 COMObject iAuthenticate;
33 boolean ignoreNextMessage, ignoreAllMessages;
34 boolean isForceTrusted;
35 Boolean canExecuteApplets;
37 static final int OLECMDID_SHOWSCRIPTERROR = 40;
38 static final short [] ACCENTS = new short [] {'~', '`', '\'', '^', '"'};
39 static final String CONSUME_KEY = "org.eclipse.swt.OleFrame.ConsumeKey"; //$NON-NLS-1$
41 public WebSite(Composite parent, int style, String progId) {
42 super(parent, style, progId);
46 protected void createCOMInterfaces () {
47 super.createCOMInterfaces();
48 iDocHostUIHandler = new COMObject(new int[]{2, 0, 0, 4, 1, 5, 0, 0, 1, 1, 1, 3, 3, 2, 2, 1, 3, 2}){
50 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
52 public long method1(long[] args) {return AddRef();}
54 public long method2(long[] args) {return Release();}
56 public long method3(long[] args) {return ShowContextMenu((int)args[0], args[1], args[2], args[3]);}
58 public long method4(long[] args) {return GetHostInfo(args[0]);}
60 public long method5(long[] args) {return ShowUI((int)args[0], args[1], args[2], args[3], args[4]);}
62 public long method6(long[] args) {return HideUI();}
64 public long method7(long[] args) {return UpdateUI();}
66 public long method8(long[] args) {return EnableModeless((int)args[0]);}
68 public long method9(long[] args) {return OnDocWindowActivate((int)args[0]);}
70 public long method10(long[] args) {return OnFrameWindowActivate((int)args[0]);}
72 public long method11(long[] args) {return ResizeBorder(args[0], args[1], (int)args[2]);}
74 public long method12(long[] args) {return TranslateAccelerator(args[0], args[1], (int)args[2]);}
76 public long method13(long[] args) {return GetOptionKeyPath(args[0], (int)args[1]);}
78 public long method14(long[] args) {return GetDropTarget(args[0], args[1]);}
80 public long method15(long[] args) {return GetExternal(args[0]);}
82 public long method16(long[] args) {return TranslateUrl((int)args[0], args[1], args[2]);}
84 public long method17(long[] args) {return FilterDataObject(args[0], args[1]);}
86 iDocHostShowUI = new COMObject(new int[]{2, 0, 0, 7, 6}){
88 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
90 public long method1(long[] args) {return AddRef();}
92 public long method2(long[] args) {return Release();}
94 public long method3(long[] args) {return ShowMessage(args[0], args[1], args[2], (int)args[3], args[4], (int)args[5], args[6]);}
96 public long method4(long[] args) {return ShowHelp(args[0], args[1], (int)args[2], (int)args[3], args[4], args[5]);}
98 iServiceProvider = new COMObject(new int[]{2, 0, 0, 3}){
100 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
102 public long method1(long[] args) {return AddRef();}
104 public long method2(long[] args) {return Release();}
106 public long method3(long[] args) {return QueryService(args[0], args[1], args[2]);}
108 iInternetSecurityManager = new COMObject(new int[]{2, 0, 0, 1, 1, 3, 4, 8, 7, 3, 3}){
110 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
112 public long method1(long[] args) {return AddRef();}
114 public long method2(long[] args) {return Release();}
116 public long method3(long[] args) {return SetSecuritySite(args[0]);}
118 public long method4(long[] args) {return GetSecuritySite(args[0]);}
120 public long method5(long[] args) {return MapUrlToZone(args[0], args[1], (int)args[2]);}
122 public long method6(long[] args) {return GetSecurityId(args[0], args[1], args[2], args[3]);}
124 public long method7(long[] args) {return ProcessUrlAction(args[0], (int)args[1], args[2], (int)args[3], args[4], (int)args[5], (int)args[6], (int)args[7]);}
126 public long method8(long[] args) {return QueryCustomPolicy(args[0], args[1], args[2], args[3], args[4], (int)args[5], (int)args[6]);}
128 public long method9(long[] args) {return SetZoneMapping((int)args[0], args[1], (int)args[2]);}
130 public long method10(long[] args) {return GetZoneMappings((int)args[0], args[1], (int)args[2]);}
132 iOleCommandTarget = new COMObject(new int[]{2, 0, 0, 4, 5}) {
134 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
136 public long method1(long[] args) {return AddRef();}
138 public long method2(long[] args) {return Release();}
140 public long method3(long[] args) {return QueryStatus(args[0], (int)args[1], args[2], args[3]);}
142 public long method4(long[] args) {return Exec(args[0], (int)args[1], (int)args[2], args[3], args[4]);}
144 iAuthenticate = new COMObject(new int[]{2, 0, 0, 3}){
146 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
148 public long method1(long[] args) {return AddRef();}
150 public long method2(long[] args) {return Release();}
152 public long method3(long[] args) {return Authenticate(args[0], args[1], args[2]);}
154 iDispatch = new COMObject (new int[] {2, 0, 0, 1, 3, 5, 8}) {
156 public long method0 (long[] args) {
158 * IDispatch check must be done here instead of in the shared QueryInterface
159 * implementation, to avoid answering the superclass's IDispatch implementation
160 * instead of this one.
162 GUID guid = new GUID ();
163 COM.MoveMemory (guid, args[0], GUID.sizeof);
164 if (COM.IsEqualGUID (guid, COM.IIDIDispatch)) {
165 OS.MoveMemory (args[1], new long[] {iDispatch.getAddress ()}, C.PTR_SIZEOF);
169 return QueryInterface (args[0], args[1]);
172 public long method1 (long[] args) {return AddRef ();}
174 public long method2 (long[] args) {return Release ();}
176 public long method3 (long[] args) {return GetTypeInfoCount (args[0]);}
178 public long method4 (long[] args) {return GetTypeInfo ((int)args[0], (int)args[1], args[2]);}
180 public long method5 (long[] args) {return GetIDsOfNames ((int)args[0], args[1], (int)args[2], (int)args[3], args[4]);}
182 public long method6 (long[] args) {return Invoke ((int)args[0], (int)args[1], (int)args[2], (int)args[3], args[4], args[5], args[6], args[7]);}
187 protected void disposeCOMInterfaces() {
188 super.disposeCOMInterfaces();
189 if (iDocHostUIHandler != null) {
190 iDocHostUIHandler.dispose();
191 iDocHostUIHandler = null;
193 if (iDocHostShowUI != null) {
194 iDocHostShowUI.dispose();
195 iDocHostShowUI = null;
197 if (iServiceProvider != null) {
198 iServiceProvider.dispose();
199 iServiceProvider = null;
201 if (iInternetSecurityManager != null) {
202 iInternetSecurityManager.dispose();
203 iInternetSecurityManager = null;
205 if (iOleCommandTarget != null) {
206 iOleCommandTarget.dispose();
207 iOleCommandTarget = null;
209 if (iAuthenticate != null) {
210 iAuthenticate.dispose();
211 iAuthenticate = null;
213 if (iDispatch != null) {
214 iDispatch.dispose ();
220 protected int AddRef() {
221 /* Workaround for javac 1.1.8 bug */
222 return super.AddRef();
226 protected int QueryInterface(long riid, long ppvObject) {
227 int result = super.QueryInterface(riid, ppvObject);
228 if (result == COM.S_OK) return result;
229 if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
230 GUID guid = new GUID();
231 COM.MoveMemory(guid, riid, GUID.sizeof);
232 if (COM.IsEqualGUID(guid, COM.IIDIDocHostUIHandler)) {
233 OS.MoveMemory(ppvObject, new long[] {iDocHostUIHandler.getAddress()}, C.PTR_SIZEOF);
237 if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) {
238 OS.MoveMemory(ppvObject, new long[] {iDocHostShowUI.getAddress()}, C.PTR_SIZEOF);
242 if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) {
243 OS.MoveMemory(ppvObject, new long[] {iServiceProvider.getAddress()}, C.PTR_SIZEOF);
247 if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
248 OS.MoveMemory(ppvObject, new long[] {iInternetSecurityManager.getAddress()}, C.PTR_SIZEOF);
252 if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) {
253 OS.MoveMemory(ppvObject, new long[] {iOleCommandTarget.getAddress()}, C.PTR_SIZEOF);
257 OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
258 return COM.E_NOINTERFACE;
261 /* IDocHostUIHandler */
263 int EnableModeless(int EnableModeless) {
264 return COM.E_NOTIMPL;
267 int FilterDataObject(long pDO, long ppDORet) {
268 return COM.E_NOTIMPL;
271 int GetDropTarget(long pDropTarget, long ppDropTarget) {
272 return COM.E_NOTIMPL;
275 int GetExternal(long ppDispatch) {
276 OS.MoveMemory (ppDispatch, new long[] {iDispatch.getAddress()}, C.PTR_SIZEOF);
281 int GetHostInfo(long pInfo) {
282 int info = IE.DOCHOSTUIFLAG_THEME | IE.DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION | IE.DOCHOSTUIFLAG_DPI_AWARE;
283 IE browser = (IE)((Browser)getParent().getParent()).webBrowser;
284 if ((browser.style & SWT.BORDER) == 0) info |= IE.DOCHOSTUIFLAG_NO3DOUTERBORDER;
285 DOCHOSTUIINFO uiInfo = new DOCHOSTUIINFO ();
286 OS.MoveMemory(uiInfo, pInfo, DOCHOSTUIINFO.sizeof);
287 uiInfo.dwFlags = info;
288 OS.MoveMemory(pInfo, uiInfo, DOCHOSTUIINFO.sizeof);
292 int GetOptionKeyPath(long pchKey, int dw) {
293 return COM.E_NOTIMPL;
297 return COM.E_NOTIMPL;
300 int OnDocWindowActivate(int fActivate) {
301 return COM.E_NOTIMPL;
304 int OnFrameWindowActivate(int fActivate) {
305 return COM.E_NOTIMPL;
309 protected int Release() {
310 /* Workaround for javac 1.1.8 bug */
311 return super.Release();
314 int ResizeBorder(long prcBorder, long pUIWindow, int fFrameWindow) {
315 return COM.E_NOTIMPL;
318 int ShowContextMenu(int dwID, long ppt, long pcmdtReserved, long pdispReserved) {
319 Browser browser = (Browser)getParent().getParent();
320 Event event = new Event();
321 POINT pt = new POINT();
322 OS.MoveMemory(pt, ppt, POINT.sizeof);
323 pt.x = DPIUtil.autoScaleDown(pt.x); // To Points
324 pt.y = DPIUtil.autoScaleDown(pt.y); // To Points
327 browser.notifyListeners(SWT.MenuDetect, event);
328 if (!event.doit) return COM.S_OK;
329 Menu menu = browser.getMenu();
330 if (menu != null && !menu.isDisposed ()) {
331 if (pt.x != event.x || pt.y != event.y) {
332 menu.setLocation (event.x, event.y);
334 menu.setVisible (true);
337 /* Show default IE popup menu */
341 int ShowUI(int dwID, long pActiveObject, long pCommandTarget, long pFrame, long pDoc) {
345 int TranslateAccelerator(long lpMsg, long pguidCmdGroup, int nCmdID) {
347 * Feature in Internet Explorer. By default the embedded Internet Explorer control runs
348 * the Internet Explorer shortcuts (e.g. Ctrl+F for Find). This overrides the shortcuts
349 * defined by SWT. The workaround is to forward the accelerator keys to the parent window
350 * and have Internet Explorer ignore the ones handled by the parent window.
352 Menu menubar = getShell().getMenuBar();
353 if (menubar != null && !menubar.isDisposed() && menubar.isEnabled()) {
354 Shell shell = menubar.getShell();
355 long hwnd = shell.handle;
356 long hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
359 OS.MoveMemory(msg, lpMsg, MSG.sizeof);
360 if (OS.TranslateAccelerator(hwnd, hAccel, msg) != 0) return COM.S_OK;
364 * By default the IE shortcuts are run. However, the shortcuts below should not run
365 * in this context. The workaround is to block IE from handling these shortcuts by
366 * answering COM.S_OK.
368 * - F5 causes a refresh, which is not appropriate when rendering HTML from memory
369 * - CTRL+L and CTRL+O show an Open Location dialog in IE8, which is undesirable and
370 * can crash in some contexts
371 * - CTRL+N opens a standalone IE, which is undesirable and can crash in some contexts
373 int result = COM.S_FALSE;
375 OS.MoveMemory(msg, lpMsg, MSG.sizeof);
376 if (msg.message == OS.WM_KEYDOWN) {
377 switch ((int)msg.wParam) {
379 OleAutomation auto = new OleAutomation(this);
380 int[] rgdispid = auto.getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$
381 Variant pVarResult = auto.getProperty(rgdispid[0]);
383 if (pVarResult != null) {
384 if (pVarResult.getType() == OLE.VT_BSTR) {
385 String url = pVarResult.getString();
386 if (url.equals(IE.ABOUT_BLANK)) result = COM.S_OK;
388 pVarResult.dispose();
393 * Do not interfere with tab traversal since it's not known
394 * if it will be within IE or out to another Control.
405 /* Do not translate/consume IE's keys for scrolling content. */
411 * Translating OS.VK_BACK, OS.VK_RETURN or OS.VK_SPACE results in the native
412 * control handling them twice (eg.- inserting two lines instead of one). So
413 * these keys are not translated here, and instead are explicitly handled
414 * in the keypress handler.
420 if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_MENU) >= 0 && OS.GetKeyState (OS.VK_SHIFT) >= 0) {
421 if (msg.wParam == OS.VK_N || IE.IEVersion >= 8) {
422 frame.setData(CONSUME_KEY, "false"); //$NON-NLS-1$
429 OS.TranslateMessage(msg);
430 frame.setData(CONSUME_KEY, "true"); //$NON-NLS-1$
435 switch (msg.message) {
438 boolean isAccent = false;
439 switch ((int)msg.wParam) {
448 int mapKey = OS.MapVirtualKey ((int)msg.wParam, 2);
450 isAccent = (mapKey & 0x80000000) != 0;
452 for (int i=0; i<ACCENTS.length; i++) {
453 int value = OS.VkKeyScan (ACCENTS [i]);
454 if (value != -1 && (value & 0xFF) == msg.wParam) {
455 int state = value >> 8;
456 if ((OS.GetKeyState (OS.VK_SHIFT) < 0) == ((state & 0x1) != 0) &&
457 (OS.GetKeyState (OS.VK_CONTROL) < 0) == ((state & 0x2) != 0) &&
458 (OS.GetKeyState (OS.VK_MENU) < 0) == ((state & 0x4) != 0)) {
459 if ((state & 0x7) != 0) isAccent = true;
469 if (isAccent) result = COM.S_OK;
475 int TranslateUrl(int dwTranslate, long pchURLIn, long ppchURLOut) {
476 return COM.E_NOTIMPL;
480 return COM.E_NOTIMPL;
485 int ShowMessage(long hwnd, long lpstrText, long lpstrCaption, int dwType, long lpstrHelpFile, int dwHelpContext, long plResult) {
486 boolean ignore = ignoreNextMessage || ignoreAllMessages;
487 ignoreNextMessage = false;
488 return ignore ? COM.S_OK : COM.S_FALSE;
491 int ShowHelp(long hwnd, long pszHelpFile, int uCommand, int dwData, long pt, long pDispatchObjectHit) {
492 Browser browser = (Browser)getParent().getParent();
493 Event event = new Event();
494 event.type = SWT.Help;
495 event.display = getDisplay();
496 event.widget = browser;
497 Shell shell = browser.getShell();
498 Control control = browser;
500 if (control.isListening(SWT.Help)) {
501 control.notifyListeners(SWT.Help, event);
504 if (control == shell) break;
505 control = control.getParent();
510 /* IServiceProvider */
512 int QueryService(long guidService, long riid, long ppvObject) {
513 if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
514 GUID guid = new GUID();
515 COM.MoveMemory(guid, riid, GUID.sizeof);
516 if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
517 OS.MoveMemory(ppvObject, new long[] {iInternetSecurityManager.getAddress()}, C.PTR_SIZEOF);
521 if (COM.IsEqualGUID(guid, COM.IIDIAuthenticate)) {
522 OS.MoveMemory(ppvObject, new long[] {iAuthenticate.getAddress()}, C.PTR_SIZEOF);
526 OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
527 return COM.E_NOINTERFACE;
530 /* IInternetSecurityManager */
532 int SetSecuritySite(long pSite) {
533 return IE.INET_E_DEFAULT_ACTION;
536 int GetSecuritySite(long ppSite) {
537 return IE.INET_E_DEFAULT_ACTION;
540 int MapUrlToZone(long pwszUrl, long pdwZone, int dwFlags) {
542 * Feature in IE. HTML rendered in memory does not enable local links
543 * but the same HTML document loaded through a local file is permitted
544 * to follow local links. The workaround is to return URLZONE_INTRANET
545 * instead of the default value URLZONE_LOCAL_MACHINE.
547 if (isForceTrusted) {
548 OS.MoveMemory(pdwZone, new int[] {IE.URLZONE_INTRANET}, 4);
551 return IE.INET_E_DEFAULT_ACTION;
554 int GetSecurityId(long pwszUrl, long pbSecurityId, long pcbSecurityId, long dwReserved) {
555 return IE.INET_E_DEFAULT_ACTION;
558 int ProcessUrlAction(long pwszUrl, int dwAction, long pPolicy, int cbPolicy, long pContext, int cbContext, int dwFlags, int dwReserved) {
559 ignoreNextMessage = false;
562 * If the current page is about:blank and is trusted then
563 * override default zone elevation settings to allow the action.
565 if (dwAction == IE.URLACTION_FEATURE_ZONE_ELEVATION) {
566 IE ie = (IE)((Browser)getParent().getParent()).webBrowser;
567 if (ie.auto != null && ie._getUrl().startsWith(IE.ABOUT_BLANK) && !ie.untrustedText) {
568 if (cbPolicy >= 4) OS.MoveMemory(pPolicy, new int[] {IE.URLPOLICY_ALLOW}, 4);
573 int policy = IE.INET_E_DEFAULT_ACTION;
575 if (dwAction >= IE.URLACTION_JAVA_MIN && dwAction <= IE.URLACTION_JAVA_MAX) {
576 if (canExecuteApplets ()) {
577 policy = IE.URLPOLICY_JAVA_LOW;
579 policy = IE.URLPOLICY_JAVA_PROHIBIT;
580 ignoreNextMessage = true;
583 if (dwAction == IE.URLACTION_ACTIVEX_RUN && pContext != 0) {
584 GUID guid = new GUID();
585 COM.MoveMemory(guid, pContext, GUID.sizeof);
586 if (COM.IsEqualGUID(guid, COM.IIDJavaBeansBridge) && !canExecuteApplets ()) {
587 policy = IE.URLPOLICY_DISALLOW;
588 ignoreNextMessage = true;
590 if (COM.IsEqualGUID(guid, COM.IIDShockwaveActiveXControl)) {
591 policy = IE.URLPOLICY_DISALLOW;
592 ignoreNextMessage = true;
595 if (dwAction == IE.URLACTION_SCRIPT_RUN) {
596 IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
597 policy = browser.jsEnabled ? IE.URLPOLICY_ALLOW : IE.URLPOLICY_DISALLOW;
600 if (policy == IE.INET_E_DEFAULT_ACTION) return IE.INET_E_DEFAULT_ACTION;
601 if (cbPolicy >= 4) OS.MoveMemory(pPolicy, new int[] {policy}, 4);
602 return policy == IE.URLPOLICY_ALLOW ? COM.S_OK : COM.S_FALSE;
605 boolean canExecuteApplets () {
607 * Executing an applet in embedded IE will crash if IE's Java plug-in
608 * launches its jre in IE's process, because this new jre conflicts
609 * with the one running eclipse. These cases need to be avoided by
610 * vetoing the running of applets.
612 * However as of Sun jre 1.6u10, applets can be launched in a separate
613 * process, which avoids the conflict with the jre running eclipse.
614 * Therefore if this condition is detected, and if the required jar
615 * libraries are available, then applets can be executed.
619 * executing applets with IE6 embedded can crash, so do not
620 * attempt this if the version is less than IE7
622 if (IE.IEVersion < 7) return false;
624 if (canExecuteApplets == null) {
625 WebBrowser webBrowser = ((Browser)getParent ().getParent ()).webBrowser;
626 String script = "try {var element = document.createElement('object');element.classid='clsid:CAFEEFAC-DEC7-0000-0000-ABCDEFFEDCBA';return element.object.isPlugin2();} catch (err) {};return false;"; //$NON-NLS-1$
627 canExecuteApplets = ((Boolean)webBrowser.evaluate (script));
628 if (canExecuteApplets.booleanValue ()) {
630 Class.forName ("sun.plugin2.main.server.IExplorerPlugin"); /* plugin.jar */ //$NON-NLS-1$
631 Class.forName ("com.sun.deploy.services.Service"); /* deploy.jar */ //$NON-NLS-1$
632 Class.forName ("com.sun.javaws.Globals"); /* javaws.jar */ //$NON-NLS-1$
633 } catch (ClassNotFoundException e) {
634 /* one or more of the required jar libraries are not available */
635 canExecuteApplets = Boolean.FALSE;
639 return canExecuteApplets.booleanValue ();
642 int QueryCustomPolicy(long pwszUrl, long guidKey, long ppPolicy, long pcbPolicy, long pContext, int cbContext, int dwReserved) {
643 return IE.INET_E_DEFAULT_ACTION;
646 int SetZoneMapping(int dwZone, long lpszPattern, int dwFlags) {
647 return IE.INET_E_DEFAULT_ACTION;
650 int GetZoneMappings(int dwZone, long ppenumString, int dwFlags) {
651 return COM.E_NOTIMPL;
654 /* IOleCommandTarget */
655 int QueryStatus(long pguidCmdGroup, int cCmds, long prgCmds, long pCmdText) {
656 return COM.E_NOTSUPPORTED;
659 int Exec(long pguidCmdGroup, int nCmdID, int nCmdExecOpt, long pvaIn, long pvaOut) {
660 if (pguidCmdGroup != 0) {
661 GUID guid = new GUID();
662 COM.MoveMemory(guid, pguidCmdGroup, GUID.sizeof);
665 * If a javascript error occurred then suppress IE's default script error dialog.
667 if (COM.IsEqualGUID(guid, COM.CGID_DocHostCommandHandler)) {
668 if (nCmdID == OLECMDID_SHOWSCRIPTERROR) return COM.S_OK;
672 * Bug in Internet Explorer. OnToolBar TRUE is also fired when any of the
673 * address bar or menu bar are requested but not the tool bar. A workaround
674 * has been posted by a Microsoft developer on the public webbrowser_ctl
675 * newsgroup. The workaround is to implement the IOleCommandTarget interface
676 * to test the argument of an undocumented command.
678 if (nCmdID == 1 && COM.IsEqualGUID(guid, COM.CGID_Explorer) && ((nCmdExecOpt & 0xFFFF) == 0xA)) {
679 IE browser = (IE)((Browser)getParent().getParent()).webBrowser;
680 browser.toolBar = (nCmdExecOpt & 0xFFFF0000) != 0;
683 return COM.E_NOTSUPPORTED;
688 int Authenticate (long hwnd, long szUsername, long szPassword) {
689 IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
690 for (int i = 0; i < browser.authenticationListeners.length; i++) {
691 AuthenticationEvent event = new AuthenticationEvent (browser.browser);
692 event.location = browser.lastNavigateURL;
693 browser.authenticationListeners[i].authenticate (event);
694 if (!event.doit) return COM.E_ACCESSDENIED;
695 if (event.user != null && event.password != null) {
696 TCHAR user = new TCHAR (0, event.user, true);
697 int size = user.length () * TCHAR.sizeof;
698 long userPtr = OS.CoTaskMemAlloc (size);
699 OS.MoveMemory (userPtr, user, size);
700 TCHAR password = new TCHAR (0, event.password, true);
701 size = password.length () * TCHAR.sizeof;
702 long passwordPtr = OS.CoTaskMemAlloc (size);
703 OS.MoveMemory (passwordPtr, password, size);
704 C.memmove (hwnd, new long[] {0}, C.PTR_SIZEOF);
705 C.memmove (szUsername, new long[] {userPtr}, C.PTR_SIZEOF);
706 C.memmove (szPassword, new long[] {passwordPtr}, C.PTR_SIZEOF);
711 /* no listener handled the challenge, so defer to the native dialog */
712 C.memmove (hwnd, new long[] {getShell().handle}, C.PTR_SIZEOF);
718 int GetTypeInfoCount (long pctinfo) {
719 C.memmove (pctinfo, new int[] {0}, 4);
723 int GetTypeInfo (int iTInfo, int lcid, long ppTInfo) {
727 int GetIDsOfNames (int riid, long rgszNames, int cNames, int lcid, long rgDispId) {
728 long[] ptr = new long[1];
729 OS.MoveMemory (ptr, rgszNames, C.PTR_SIZEOF);
730 int length = OS.wcslen (ptr[0]);
731 char[] buffer = new char[length];
732 OS.MoveMemory (buffer, ptr[0], length * 2);
733 String functionName = String.valueOf (buffer);
734 int result = COM.S_OK;
735 int[] ids = new int[cNames]; /* DISPIDs */
736 if (functionName.equals ("callJava")) { //$NON-NLS-1$
737 for (int i = 0; i < cNames; i++) {
741 result = COM.DISP_E_UNKNOWNNAME;
742 for (int i = 0; i < cNames; i++) {
743 ids[i] = COM.DISPID_UNKNOWN;
746 OS.MoveMemory (rgDispId, ids, cNames * 4);
750 int Invoke (int dispIdMember, long riid, int lcid, int dwFlags, long pDispParams, long pVarResult, long pExcepInfo, long pArgErr) {
751 IE ie = (IE)((Browser)getParent ().getParent ()).webBrowser;
752 Map<Integer, BrowserFunction> functions = ie.functions;
753 if (functions == null) {
754 if (pVarResult != 0) {
755 OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
760 DISPPARAMS dispParams = new DISPPARAMS ();
761 COM.MoveMemory (dispParams, pDispParams, DISPPARAMS.sizeof);
762 if (dispParams.cArgs != 3) {
763 if (pVarResult != 0) {
764 OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
769 long ptr = dispParams.rgvarg + 2 * Variant.sizeof;
770 Variant variant = Variant.win32_new (ptr);
771 if (variant.getType () != COM.VT_I4) {
773 if (pVarResult != 0) {
774 OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
778 int index = variant.getInt ();
781 if (pVarResult != 0) {
782 OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
787 ptr = dispParams.rgvarg + Variant.sizeof;
788 variant = Variant.win32_new (ptr);
789 int type = variant.getType ();
790 if (type != COM.VT_BSTR) {
792 if (pVarResult != 0) {
793 OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
797 String token = variant.getString ();
800 variant = Variant.win32_new (dispParams.rgvarg);
801 BrowserFunction function = functions.get (index);
802 Object returnValue = null;
803 if (function != null && token.equals (function.token)) {
805 Object temp = convertToJava (variant);
806 if (temp instanceof Object[]) {
807 Object[] args = (Object[])temp;
809 returnValue = function.function (args);
810 } catch (Exception e) {
811 /* exception during function invocation */
812 returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
815 } catch (IllegalArgumentException e) {
816 /* invalid argument value type */
817 if (function.isEvaluate) {
818 /* notify the function so that a java exception can be thrown */
819 function.function (new String[] {WebBrowser.CreateErrorString (new SWTException (SWT.ERROR_INVALID_RETURN_VALUE).getLocalizedMessage ())});
821 returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
826 if (pVarResult != 0) {
828 variant = convertToJS (returnValue);
829 } catch (SWTException e) {
830 /* invalid return value type */
831 variant = convertToJS (WebBrowser.CreateErrorString (e.getLocalizedMessage ()));
833 Variant.win32_copy (pVarResult, variant);
839 Object convertToJava (Variant variant) {
840 switch (variant.getType ()) {
842 case OLE.VT_NULL: return null;
843 case OLE.VT_BSTR: return variant.getString ();
844 case OLE.VT_BOOL: return variant.getBoolean ();
850 return variant.getDouble ();
851 case OLE.VT_DISPATCH: {
852 Object[] args = null;
853 OleAutomation auto = variant.getAutomation ();
854 TYPEATTR typeattr = auto.getTypeInfoAttributes ();
855 if (typeattr != null) {
856 GUID guid = new GUID ();
857 guid.Data1 = typeattr.guid_Data1;
858 guid.Data2 = typeattr.guid_Data2;
859 guid.Data3 = typeattr.guid_Data3;
860 guid.Data4 = typeattr.guid_Data4;
861 if (COM.IsEqualGUID (guid, COM.IIDIJScriptTypeInfo)) {
862 int[] rgdispid = auto.getIDsOfNames (new String[] {"length"}); //$NON-NLS-1$
863 if (rgdispid != null) {
864 Variant varLength = auto.getProperty (rgdispid[0]);
865 int length = varLength.getInt ();
866 varLength.dispose ();
867 args = new Object[length];
868 for (int i = 0; i < length; i++) {
869 rgdispid = auto.getIDsOfNames (new String[] {String.valueOf (i)});
870 if (rgdispid != null) {
871 Variant current = auto.getProperty (rgdispid[0]);
873 args[i] = convertToJava (current);
875 } catch (IllegalArgumentException e) {
876 /* invalid argument value type */
886 SWT.error (SWT.ERROR_INVALID_ARGUMENT);
893 SWT.error (SWT.ERROR_INVALID_ARGUMENT);
897 Variant convertToJS (Object value) {
901 if (value instanceof String) {
902 return new Variant ((String)value);
904 if (value instanceof Boolean) {
905 return new Variant (((Boolean)value).booleanValue ());
907 if (value instanceof Number) {
908 return new Variant (((Number)value).doubleValue ());
910 if (value instanceof Object[]) {
911 /* get IHTMLDocument2 */
912 IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
913 OleAutomation auto = browser.auto;
914 int[] rgdispid = auto.getIDsOfNames (new String[] {"Document"}); //$NON-NLS-1$
915 if (rgdispid == null) return new Variant ();
916 Variant pVarResult = auto.getProperty (rgdispid[0]);
917 if (pVarResult == null) return new Variant ();
918 if (pVarResult.getType () == COM.VT_EMPTY) {
919 pVarResult.dispose ();
920 return new Variant ();
922 OleAutomation document = pVarResult.getAutomation ();
923 pVarResult.dispose ();
925 /* get IHTMLWindow2 */
926 rgdispid = document.getIDsOfNames (new String[] {"parentWindow"}); //$NON-NLS-1$
927 if (rgdispid == null) {
929 return new Variant ();
931 pVarResult = document.getProperty (rgdispid[0]);
932 if (pVarResult == null || pVarResult.getType () == COM.VT_EMPTY) {
933 if (pVarResult != null) pVarResult.dispose ();
935 return new Variant ();
937 OleAutomation ihtmlWindow2 = pVarResult.getAutomation ();
938 pVarResult.dispose ();
941 /* create a new JS array to be returned */
942 rgdispid = ihtmlWindow2.getIDsOfNames (new String[] {"Array"}); //$NON-NLS-1$
943 if (rgdispid == null) {
944 ihtmlWindow2.dispose ();
945 return new Variant ();
947 Variant arrayType = ihtmlWindow2.getProperty (rgdispid[0]);
948 ihtmlWindow2.dispose ();
949 IDispatch arrayTypeDispatch = arrayType.getDispatch ();
950 long[] result = new long[1];
951 int rc = arrayTypeDispatch.QueryInterface (COM.IIDIDispatchEx, result);
952 arrayType.dispose ();
953 if (rc != COM.S_OK) return new Variant ();
955 IDispatchEx arrayTypeDispatchEx = new IDispatchEx (result[0]);
957 long resultPtr = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
958 DISPPARAMS params = new DISPPARAMS ();
959 rc = arrayTypeDispatchEx.InvokeEx (COM.DISPID_VALUE, COM.LOCALE_USER_DEFAULT, COM.DISPATCH_CONSTRUCT, params, resultPtr, null, 0);
960 if (rc != COM.S_OK) {
961 OS.GlobalFree (resultPtr);
962 return new Variant ();
964 Variant array = Variant.win32_new (resultPtr);
965 OS.GlobalFree (resultPtr);
967 /* populate the array */
968 Object[] arrayValue = (Object[])value;
969 int length = arrayValue.length;
970 auto = array.getAutomation ();
971 int[] rgdispids = auto.getIDsOfNames (new String[] {"push"}); //$NON-NLS-1$
972 if (rgdispids != null) {
973 for (int i = 0; i < length; i++) {
974 Object currentObject = arrayValue[i];
976 Variant variant = convertToJS (currentObject);
977 auto.invoke (rgdispids[0], new Variant[] {variant});
979 } catch (SWTException e) {
980 /* invalid return value type */
990 SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);