Eclipse RCP Project Explorer focus event - events

Is there a way to detect when the user makes focus on the Project Explorer window in a RCP application? Is there an event I could use?
I researched and found that Project Explorer's id is org.eclipse.ui.navigator.ProjectExplorer but I still didn't find any solution to my problem.

You can use org.eclipse.ui.IPartListener to listen for changes to which part is active (and several other events).
You call the IPartService addPartListener method to set this up. You can get the part service in several ways depending on where you code is running. One of these is:
IPartService partService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();
partService.addPartListener(listener);

Related

Adding my app to Explorer Context Menu

I am looking into adding a link to my app to the Explorer (windows) context menu. I've looked around for how to do this. I have done it and it works just fine by adding a key to
HKEY_CLASSES_ROOT\*\shell
Searching the web I found this:
http://www.codeproject.com/Articles/441/The-Complete-Idiot-s-Guide-to-Writing-Shell-Extens
But this seemed so simple (the *\shell method)
http://www.howtogeek.com/107965/how-to-add-any-application-shortcut-to-windows-explorers-context-menu/
HOWEVER no app(on my computer) does this (HKEY_CLASSES_ROOT*\shell) and I wonder if this is not the best solution. I think most apps I have use an inproc dll to work with Explorer. I don't know if that's why they don't go with the *\shell method or there's some other reason why this is not the best way. I could convert my app to an inproc dll if I had to but that seems unnecessary to me if I can use the *\shell method.
OF COURSE the big reason is that I have to logged in as Administrator to do this (*\shell). I was thinking of adding a separate little file that the admins would run. Which seems like a better way in a corporate environment (or any where users are not logged in as admins).

Visual Studio Extension: Wait for all projects to complete loading with IVsSolutionEvents OnAfterOpenSolution

I am looking for an event/interface to use that notifies me once all projects have loaded in a solution after opening a solution.
I have implemented OnAfterOpenSolution in IVsSolutionEvents2 interface. This gets called immediately after the solution opens... so any code I run against the UI thread, even asycnhronously, locks up the IDE prior to the project(s) loading.
Is there a similar technique to implementing `OnAfterOpenSolution', that is called once all the projects for the solution have opened?
The OnAfterBackgroundSolutionLoadComplete event in the IVsSolutionLoadEvents interface is fired after all projects for the solution have completed loading. The implementation for this will still need to implement or extend from an implementation of one of the IVsSolutionEvents interfaces in order to attach the event using IVsSolution.AdviseSolutionEvents(..) method.
Upon Further investigation in this area, the OnAfterBackgroundSolutionLoadComplete only occurs if projects are set to load in the background. If the background loading has been disabled this event will not occur. You will likely also have to implement IVsSolutionLoadManager and ensure that at least 1 project has a background load priority if you intend to rely on the OnAfterBackgroundSolutionLoadComplete event, or switch based on how the user has set their loading priority.

IsWindow(activeX.GetSafeHwnd()) always false after upgrade to VS2010

I have an MFC application that uses an ancient (circa 1999) third-party ActiveX control.
Since upgrading the project from VS2008 to VS2010, I'm having problems...
In the OnSize handler of the parent dialog IsWindow always returns false for the handle returned by control.GetSafeHwnd(), even when GetSafeHwnd() returns a non-NULL value. The rest of the control's parent dialog is displayed fine, but it doesn't seem to respond to any input.
I've seen this article, but GetSafeHwnd() isn't returning NULL in this case (after the first time that it is called, which is before the control is instantiated).
The control does cause the trace message "Control wants to be windowless" to be output when it's loaded. However it also does this when compiled in VS2008, so this may be a red herring. Searching for this message points me to creating a class derived from COleControlSite, and denying the control windowless-ness, but it seems there are no good example of this available, and as I say, it's not clear that this is really the cause of the problem.
I've also found this issue mentioned on MSDN's VS2010 porting page:
"An ActiveX control compiled by using Visual C++ 6.0, when embedded in
a dialog box in a project developed by using Visual C++ 2010, may
cause your program to assert at run time. In this situation, open the
ATL or MFC project associated with the ActiveX control in Visual C++
2010, and recompile it.. The assert will be in the file occcont.cpp,
on this line in source: ASSERT(IsWindow(pTemp->m_hWnd))."
I assume that there's something about VS6-compiled ActiveX controls that causes the window handles to be treated as invalid by the current Win32 implementation of IsWindow. The suggested solution is of course unhelpful as it's a third-party control, and we can't recompile it.
Has anyone managed to get around this?
I've already found solutions for VS2010 projects not running on Windows 2000, and errors linking to ODBC, but don't seem to be able to find anything on this one.
Thanks,
Chris
I didn't find a solution to this in the end - upgraded the controls to a VS2010-compatible version.
For what it's worth: if you don't care whether the control will appear transparent or not, you may force the control to have a window anyway - even though it can operate without a window.
You see, the ActiveX control must first ask the container (the window which will host the control) if it's okay to be activated without a window. This is simply because not all containers support windowless activation.
If this interface (IOleInPlaceSiteWindowless) returns okay then it proceeds with this special windowless activation, if not a window will be created for the control as normal.
Disclaimer:
I don't know if this 'unnecessary' window will make the assertion failure go away. In other words: I don't know if the window handle is passed down 'deep' enough into the AX control.
More about the IOleInPlaceSiteWindowless interface:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682300(v=vs.85).aspx

Start Internet Explorer 8 in a separate process using vbscript

Due to the recently added "feature" in IE8 where new windows are automatically associated with a single session, some of our code is behaving erratically.
This is because a separate app would launch a new IE window when it was activated, and once the user was finished, close the window. This worked fine in IE7 because the session information in the windows stayed separate. However in IE8, since the session is shared among IE windows, we find that the "pop up" app would corrupt the session on the first app.
I have read about the nomerge switch, so that is a workaround, but I was wondering if there was a way of working the solution into the "CreateObject" of vbscript; i.e:
Dim ieWin As Object
Set ieWin = CreateObject("InternetExplorer.Application")
Is there a way of sending parameters when calling the CreateObject function?
No, there's no way to use COM to create an IE instance that specifies this behavior (or any of the others, e.g. InPrivate, No Add-ons, etc). The only thing you can do is create an automation instance that defaults to MediumIL using the CLSID provided for that purpose. http://blogs.msdn.com/b/ieinternals/archive/2011/08/03/internet-explorer-automation-protected-mode-lcie-default-integrity-level-medium.aspx
If you have control over the web application you are loading with your IE window you can set it's session to "cookieless" (http://msdn.microsoft.com/en-us/library/aa479314.aspx) which will avoid the issues you're having with multiple instances.
The solution we ended up going with, although it's more a work around than anything else - was assigning a new url to the popped up window.
Previously, it worked as follows:
Call centre agents would be using our internal app for other duties
e.g. "http://internalsite/somepage.faces" on a day to day basis.
When they got a phone call, a third party app would fire up
"http://internalsite/customerdetails.faces". This caused the issues mentioned above.
The solution we went with:
We assigned "http://internalsite/customerdetails.faces" it's own url e.g."http://customerdetailminisite/customer.faces".
This way the call center agent could keep their main window open for other stuff and still be able to handle calls when they came in.

Can I create a Visual Studio macro to launch a specific project in the debugger?

My project has both client and server components in the same solution file. I usually have the debugger set to start them together when debugging, but it's often the case where I start the server up outside of the debugger so I can start and stop the client as needed when working on client-side only stuff. (this is much faster).
I'm trying to save myself the hassle of poking around in Solution Explorer to start individual projects and would rather just stick a button on the toolbar that calls a macro that starts the debugger for individual projects (while leaving "F5" type debugging alone to start up both processess).
I tried recording, but that didn't really result in anything useful.
So far all I've managed to do is to locate the project item in the solution explorer:
Dim projItem As UIHierarchyItem
projItem = DTE.ToolWindows.SolutionExplorer.GetItem("SolutionName\ProjectFolder\ProjectName").Select(vsUISelectionType.vsUISelectionTypeSelect)
(This is based loosely on how the macro recorder tried to do it. I'm not sure if navigating the UI object model is the correct approach, or if I should be looking at going through the Solution/Project object model instead).
Ok. This appears to work from most UI (all?) contexts provided the solution is loaded:
Sub DebugTheServer()
DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate()
DTE.ActiveWindow.Object.GetItem("Solution\ServerFolder\ServerProject").Select(vsUISelectionType.vsUISelectionTypeSelect)
DTE.Windows.Item(Constants.vsWindowKindOutput).Activate()
DTE.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Debug.Startnewinstance")
End Sub
From a C# add-in, the following worked for me:
Dte.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate();
Dte.ToolWindows.SolutionExplorer.GetItem("SolutionName\\SolutionFolderName\\ProjectName").Select(vsUISelectionType.vsUISelectionTypeSelect);

Resources