Detecting code windows switching between toolwindowpane

Source: Internet
Author: User

Being new to the SDK and studio extensibility I thought that being able to track the active code window wocould be easy. I was wrong.

 

Here is what I have and hoping someone wocould be willing to steer me in the right ction.

 

I have a toolwindow which I create inside my package. I want the toolwindows content to be only controlled by the active window. I have been looking atIvsmonitorselectionInterface but I guess I just don't understand the extensibility model of vs very well. I have also looked at the runningdocumentstable which I believe maybe cocould work but have a gut feeling telling me this is not the right way to go. cocould be wrong.

 

Anyways, if someone wocould be willing to help me out that wocould be great. Thanks so much in advance.

 

John

 

 

==========================================

 

 

Apart from the main ide window (DTE. mainwindow) There are two kind of Windows (DTE. Windows ):

 

-Document windows, such as code or designer windows

-Toolwindows, which can be floating, docked (such as the Solution Explorer) or tabbed (like a document window, such as the Object Browser ).

 

And there are two concepts:

 

-The active window, which can be a toolwindow or a document window

-The active document, which can be active even if its window is not active because a toolwindow is active

 

A document (envdte. document) can have one or more windows (document. windows), for example a Form Designer window and a code window, and the active one is document. activewindow ). on the other hand, an envdte. window can have a document (window. document) associated.

 

You can have the active window with DTE. activewindow, which can return a toolwindow or a document window.

 

You can have the active document with DTE. activedocument, which can return a document even if its window is not active (because a toolwindow is active ).

 

Some tools want to act on a document only if its window is active (DTE. activedocument. activewindow = DTE. activewindow) while want to act on the active document even if a toolwindow is active. you have to decide your behavior. notice that it a toolwindow such as the Object Browser (which is tabbed) is active, it is difficult for the user to say which document is active, because its window is not the selected tabbed one. this does not happen if the toolwindow is docked rather than tabbed.

==========================================

 

I recently tackled this problem and blogged about it. For something that seems like it shoshould be very straightforward, it wasn't. There's even a page in the SDK help that tries to describeHow to do thisBut misses several of the possible scenarios. my goal was to create a class that wocould be able to fire off "created", "gotfocus" and "lostfocus" and "closed" events for the lifecycle of any code window. the problem is, you don't care if an editor loses focus to a docked tool window, you only care if it loses focus to another Tabbed Document (in which case it's hidden ).

 

In order to do this, the class needs to implement two interfaces: ivsrunningdocumenttableevents and ivsselectionevents. the first interface will modify y our class about changes to the status of all open documents. the second will continue y us When Visual Studio detects a selection change of any kind, more on this later. the first step is to have the class implement these interfaces and register for callbacks on them, which is described in the SDK help documentation.

 

Note:When I said that ivsrunningdocumenttableevents tracks open documents, it's important to understand what that means because it effects the implementation. open documents include code editors, property editors, designers,NotTabbed tool windows. Because of that, we can't use ivsrunningdocumenttableevents to reliably tell us when an editor has lost focus because it doesn't track tabbed tool windows.

 

We're interested in code editors only. when we get a call to our ivsrunningdocumenttableevents. onbeforedocumentwindowshow implementation, the way to detect a valid code editor is to call vsshellutilities. gettextview and pass in the value of the pframe parameter. if you get a valid ivstextview object back, we have an editor. inside this function, we are specifically interested in editor creation. if the editor was just created, the ffirstshow parameter will be 1. when this is the case, we can call our "created" event to convert y that a code editor was created. the onafterdocumentwindowhide is only called when a window is closed, not when it loses focus. when this is the called, we can call our "closed" event to publish y that a code editor was closed. at this point, you have a good implementation for detecting the opening and closing of editor windows.

 

We still want to know when the editors get focus or lose focus. to determine this, we need to implement the ivsselectionevents interface, specifically the onelementvaluechanged function. this function will be called if the "Selection", or active object, changes to anything.

 

To determine a change in editor focus:

  1. Check if the elementid parameter is equal to constants. seid_windowframe. If not, just return.
  2. Determine if the varvaluenew parameter implements ivswindowframe. If so, cast it.
  3. We are only interested in when we lose focus to another Tabbed Document, so get the _ vsfpropid. vsfpropid_framemode property of the window frame. if it is 2, then it is a Tabbed Document (yes, 2 is a magic number, but I don't know the enum that this value matches up ). if it's not a Tabbed Document, then just return.
  4. Call vsshellutilities. gettextview and pass in the value of the varvaluenew parameter. If you get a valid ivstextview object back, then an editor window has gotten focus and you can call the "gotfocus" event.
  5. Determine if the varvalueold parameter implements ivswindowframe. If so, cast it.
  6. Call vsshellutilities. gettextview and pass in the value of the varvalueold parameter. If you get a valid ivstextview object back, then that editor window has lost focus and you can call the "lostfocus" event.

This can be obviusly be extended in every ways, but it's a good basis for code window tracking and something that definitely isn't immediately intuitive when working with vsip. Good luck!

 

========================================================

 

Slush_puppy

 

I think I follow what you are saying. But right now I a little stuck on"The first step is to have the class implement these interfaces and register for callbacks on them, which is described in the SDK help documentation."I can't seem to find information on how to register for callbacks. sorry if these questions are bad .. but I'm just learning this vs extensibility stuff and it is a bit overwellming at first. I can totally follow you logic in this new class but I can't seem to find information on how to register for callbacks.

 

Thanks for you help slush_puppy

 

John

 

========================================================

 

Here's some sample code to get you going... you'll need two member uint variables called cookies that are IDs that these services will assign to you. you'll use them to unsubscribe from events later.

Private uint m_rdtcookie;
Private uint m_shellmonitorcookie;

Now Subscribe to the events:

Ivsrunningdocumenttable RDT = package. getglobalservice (typeof (svsrunningdocumenttable) as ivsrunningdocumenttable;
If (RDT! = NULL)
RDT. adviserunningdoctableevents (this, out m_rdtcookie );

Ivsmonitorselection MS = package. getglobalservice (typeof (svsshellmonitorselection) as ivsmonitorselection;
If (MS! = NULL)
Ms. adviseselectionevents (this, out m_shellmonitorcookie );

Once you subscribe for those events, you will get callbacks to the functions you implement on those interfaces.

To unsubscribe, do the following in say, a dispose method or something:

Ivsrunningdocumenttable RDT = msvsshell. Package. getglobalservice (typeof (svsrunningdocumenttable) as ivsrunningdocumenttable;
If (RDT! = NULL)
RDT. unadviserunningdoctableevents (m_rdtcookie );

Ivsmonitorselection MS = msvsshell. Package. getglobalservice (typeof (svsshellmonitorselection) as ivsmonitorselection;
If (MS! = NULL)
Ms. unadviseselectionevents (m_shellmonitorcookie );
======================================

Slush_puppy

 

Thanks for all your help. I have it all working now responding to window events and everything. next I just have to get the logic for my package in there. anyway, the one thing that I wanted to maybe help you out with is the magic number (2 ). I believe I have found the enum for that. check outVsframemode, It has for values: vsfm_dock, vsfm_float, vsfm_floatonly and vsfm_mdichild. Hope this helps you out a bit also.

 

Thanks for all your help. I may need more as I move along but for now I'm doing pretty good.

John

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.