« Accessing project properties from a VS macroVSIP 2005: Managed VSPackages »

VSIP 2005: Tracking the active VS window

03/09/05

Permalink 04:36:51 pm
Categories: General, Programming, .NET, VSIP

VSIP 2005: Tracking the active VS window

In a VSPackage using the Managed Package Framework (MPF), how do you track the active editor pane in VS?

To start with, I create a new VSPackage project (New project -> Other project types -> Extensibility -> Visual Studio Integration Package) and have the wizard create a C# based project with a tool window for me. From the standard button click (to keep things under control easily), I run the following initialization code:

DTE dte = (DTE) GetService(typeof(DTE));

Window outputWindow = (Window) dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
outputWindow.Visible = true;
outputPane = ((OutputWindow) outputWindow.Object).OutputWindowPanes.Add("Active window tracking");
outputPane.Activate( );

IVsMonitorSelection monitorSelection = (IVsMonitorSelection) GetService(typeof(SVsShellMonitorSelection));
monitorSelection.AdviseSelectionEvents(this, out myCookie);

Two different things are being done here:

  1. An output pane is installed into the VS output window, titled Active window tracking, that I can use throughout my package to output debug information. The output pane is stored in a field of type OutputWindowPane, to be used later.
  2. The last two lines query the IVsMonitorSelection service from the VS shell, and install my class as an event receiver for event pertaining to selections. A selection in VS can be for any type of object that the IDE deals with, so windows are one such type. The cookie that's returned by the call to AdviseSelectionEvents isn't important for us, it's stored away in a field of uint type.

Now the class has to implement the interface IVsSelectionEvents to be able to receive notifications about selections. The three methods of the interface are implemented here:

int IVsSelectionEvents.OnElementValueChanged(uint elementid, object varValueOld, object varValueNew) {
  if (elementid == (uint) VSConstants.VSSELELEMID.SEID_WindowFrame) {
    string oldCaption = GetWindowFrameCaption((IVsWindowFrame) varValueOld);
    string newCaption = GetWindowFrameCaption((IVsWindowFrame) varValueNew);
    LogWindowChange(oldCaption, newCaption);
  }
  return VSConstants.S_OK;
}

int IVsSelectionEvents.OnSelectionChanged(IVsHierarchy pHierOld, uint itemidOld, IVsMultiItemSelect 
  pMISOld, ISelectionContainer pSCOld, IVsHierarchy pHierNew, uint itemidNew, IVsMultiItemSelect 
  pMISNew, ISelectionContainer pSCNew) {
  return VSConstants.S_OK;
}

int IVsSelectionEvents.OnCmdUIContextChanged(uint dwCmdUICookie, int fActive) {
  return VSConstants.S_OK;
}

As you can see, the only method of interest to me is the OnElementValueChanged method, in which I evaluate the elementid to make sure that the given element is indeed a WindowFrame and I extract the window caption for demonstration purposes, which is then shown in the output window I installed in the beginning. Here are the missing helper functions:

void Log(string text ) {
  if (outputPane != null)
    outputPane.OutputString(text + Environment.NewLine);
}

void LogWindowChange(string oldCaption, string newCaption) {
  Log("Focus changed from '" + oldCaption + "' to '" + newCaption + "'");
}

string GetWindowFrameCaption(IVsWindowFrame frame) {
  object result = null;
  if (frame != null)
    frame.GetProperty((int) __VSFPROPID.VSFPROPID_Caption, out result);
  return (string) result;
}

Have fun!

1 comment

Comment from: Sheshonq [Visitor] Email
SheshonqVery good article
I have an issue and I will be so gratefull if you help me. I developed a VS Package project. When I right click an item in the project explorer my custom menu item appears as expected. I want to get that item in the MenuCallBack() method of the package class but I failed
private void MenuItemCallback(object sender, EventArgs e)
{

IVsUIShell uiShell=(IVsUIShell)GetService(typeof(SVsUIShell));

IVsWindowFrame windFrame;
object obj;
string pbstrData;
object ppunck;
int y = uiShell.GetCurrentBFNavigationItem(out windFrame, out pbstrData, out ppunck);
MessageBox.Show(windFrame.ToString());
}
06/21/11 @ 16:40

Leave a comment


Your email address will not be revealed on this site.
(Line breaks become <br />)
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Please complete the song title below. Hint: enter 's', 'a', 't', 'i', 's', 'f', 'a', 'c', 't', 'i', 'o', 'n'
antispam test

Enter your email address:

Search

Oliver
MVP logo
November 2014
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30