Bug 237102 - [OLE] OleControlSite with Excel.Sheet renders deactivated view improperly - back ported for 3.4.2
diff --git a/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java b/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java
index f8648ec..322511b 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java
@@ -939,7 +939,7 @@
 	}
 	return COM.S_OK;
 }
-private int OnUIDeactivate(int fUndoable) {
+int OnUIDeactivate(int fUndoable) {
 	// currently, we are ignoring the fUndoable flag
 	if (frame == null || frame.isDisposed()) return COM.S_OK;
 	state = STATE_INPLACEACTIVE;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleControlSite.java b/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleControlSite.java
index 0ab8e9f..38f4fd5 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleControlSite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleControlSite.java
@@ -65,6 +65,8 @@
 	// work around for IE destroying the caret
 	static int SWT_RESTORECARET;
 	
+	static final String SHELL_PROG_ID = "Shell.Explorer";	//$NON-NLS-1$
+
 /**
  * Create an OleControlSite child widget using style bits
  * to select a particular look or set of properties.
@@ -586,6 +588,12 @@
 	return COM.S_OK;
 }
 void onFocusIn(Event e) {
+	String progID = getProgramID();
+	if (progID == null) return;
+	if (!progID.startsWith(SHELL_PROG_ID)) {
+		super.onFocusIn(e);
+		return;
+	}
 	if (objIOleInPlaceObject == null) return;
 	doVerb(OLE.OLEIVERB_UIACTIVATE);
 	if (isFocusControl()) return;
@@ -595,40 +603,45 @@
 	OS.SetFocus(phwnd[0]);
 }
 void onFocusOut(Event e) {
-	if (objIOleInPlaceObject != null) {
-		/*
-		* Bug in Windows.  When IE7 loses focus and UIDeactivate()
-		* is called, IE destroys the caret even though it is
-		* no longer owned by IE.  If focus has moved to a control
-		* that shows a caret then the caret disappears.  The fix 
-		* is to detect this case and restore the caret.
-		*/
-		int threadId = OS.GetCurrentThreadId();
-		GUITHREADINFO lpgui1 = new GUITHREADINFO();
-		lpgui1.cbSize = GUITHREADINFO.sizeof;
-		OS.GetGUIThreadInfo(threadId, lpgui1);
-		objIOleInPlaceObject.UIDeactivate();
-		if (lpgui1.hwndCaret != 0) {
-			GUITHREADINFO lpgui2 = new GUITHREADINFO();
-			lpgui2.cbSize = GUITHREADINFO.sizeof;
-			OS.GetGUIThreadInfo(threadId, lpgui2);
-			if (lpgui2.hwndCaret == 0 && lpgui1.hwndCaret == OS.GetFocus()) {
-				if (SWT_RESTORECARET == 0) {
-					SWT_RESTORECARET = OS.RegisterWindowMessage (new TCHAR (0, "SWT_RESTORECARET", true));
-				}
-				/*
-				* If the caret was not restored by SWT, put it back using
-				* the information from GUITHREADINFO.  Note that this will
-				* not be correct when the caret has a bitmap.  There is no
-				* API to query the bitmap that the caret is using.
-				*/
-				if (OS.SendMessage (lpgui1.hwndCaret, SWT_RESTORECARET, 0, 0) == 0) {
-					int width = lpgui1.right - lpgui1.left;
-					int height = lpgui1.bottom - lpgui1.top;
-					OS.CreateCaret (lpgui1.hwndCaret, 0, width, height);
-					OS.SetCaretPos (lpgui1.left, lpgui1.top);
-					OS.ShowCaret (lpgui1.hwndCaret);
-				}
+	if (objIOleInPlaceObject == null) return;
+	String progID = getProgramID();
+	if (progID == null) return;
+	if (!progID.startsWith(SHELL_PROG_ID)) {
+		super.onFocusOut(e);
+		return;
+	}
+	/*
+	* Bug in Windows.  When IE7 loses focus and UIDeactivate()
+	* is called, IE destroys the caret even though it is
+	* no longer owned by IE.  If focus has moved to a control
+	* that shows a caret then the caret disappears.  The fix 
+	* is to detect this case and restore the caret.
+	*/
+	int threadId = OS.GetCurrentThreadId();
+	GUITHREADINFO lpgui1 = new GUITHREADINFO();
+	lpgui1.cbSize = GUITHREADINFO.sizeof;
+	OS.GetGUIThreadInfo(threadId, lpgui1);
+	objIOleInPlaceObject.UIDeactivate();
+	if (lpgui1.hwndCaret != 0) {
+		GUITHREADINFO lpgui2 = new GUITHREADINFO();
+		lpgui2.cbSize = GUITHREADINFO.sizeof;
+		OS.GetGUIThreadInfo(threadId, lpgui2);
+		if (lpgui2.hwndCaret == 0 && lpgui1.hwndCaret == OS.GetFocus()) {
+			if (SWT_RESTORECARET == 0) {
+				SWT_RESTORECARET = OS.RegisterWindowMessage (new TCHAR (0, "SWT_RESTORECARET", true));
+			}
+			/*
+			* If the caret was not restored by SWT, put it back using
+			* the information from GUITHREADINFO.  Note that this will
+			* not be correct when the caret has a bitmap.  There is no
+			* API to query the bitmap that the caret is using.
+			*/
+			if (OS.SendMessage (lpgui1.hwndCaret, SWT_RESTORECARET, 0, 0) == 0) {
+				int width = lpgui1.right - lpgui1.left;
+				int height = lpgui1.bottom - lpgui1.top;
+				OS.CreateCaret (lpgui1.hwndCaret, 0, width, height);
+				OS.SetCaretPos (lpgui1.left, lpgui1.top);
+				OS.ShowCaret (lpgui1.hwndCaret);
 			}
 		}
 	}
@@ -636,10 +649,17 @@
 private int OnFocus(int fGotFocus) {
 	return COM.S_OK;
 }
-protected int OnUIDeactivate(int fUndoable) {
+int OnUIDeactivate(int fUndoable) {
 	// controls don't need to do anything for
 	// border space or menubars
+	if (frame == null || frame.isDisposed()) return COM.S_OK;
 	state = STATE_INPLACEACTIVE;
+	frame.SetActiveObject(0,0);
+	redraw();
+	Shell shell = getShell();
+	if (isFocusControl() || frame.isFocusControl()) {
+		shell.traverse(SWT.TRAVERSE_TAB_NEXT);
+	}
 	return COM.S_OK;
 }
 protected int QueryInterface(int /*long*/ riid, int /*long*/ ppvObject) {