0

VsPackage 2010 - Accessing underlying UserControl inside a Custom Editor using IVsWindowFrame

by Syed Aziz ur Rahman 12. October 2012 17:07

By using the sample I mentioned in my previous post here (VsPackage 2010 - Custom Tool Window using IVsHierarchy and IVsUIHierarchy ), I was able to make a custom tool window and a custom editor by Implementing IVsUIHierarchy and IVsHierarchy. Now on an UI event in my custom tool window e.g. double click, I am opening my custom Editor by calling "OpenSpecificEditor". As you know, OpenSpecificEditor method has a out parameter (handle) of IVsWindowFrame which you can use to show the editor. It is working fine and editor is getting opened. A call would be like this.

private IVsWindowFrame OpenEditor(HierarchyTreeNode selectedItem)
{
	IVsUIShellOpenDocument openDoc = (IVsUIShellOpenDocument)GetService(typeof(SVsUIShellOpenDocument));
	IVsWindowFrame editorFrame;
	Guid guidEditorType = GuidList.guidEditorFactory;
	Guid guidLogView = VSConstants.LOGVIEWID.Primary_guid;
	IOleServiceProvider spContext = (IOleServiceProvider)GetService(typeof(IOleServiceProvider));
	string moniker = selectedItem.Text;

	int hr = openDoc.OpenSpecificEditor(0, moniker, ref guidEditorType, "",
	ref guidLogView, "Vj Editor - ", (IVsUIHierarchy)this, (uint)selectedItem.ID,
	IntPtr.Zero, spContext, out editorFrame);

	if (editorFrame != null)
	{
		editorFrame.Show();
	}
	return editorFrame;
}

 Similarly when I tried to get a reference of already created editor using "IsDocumentOpen" method, I got an object of same IVsWindowFrame class. Sample code will be like 

private IVsWindowFrame AddEditorIfNotExist(HierarchyTreeNode hNode)
{
    IVsUIHierarchy outHierOwner = null;
    UInt32[] outHierItem = null;
    IVsWindowFrame editorFrame;
    int open;
    Guid guidLogView = VSConstants.LOGVIEWID.Primary_guid;

    IVsUIShellOpenDocument openDoc = (IVsUIShellOpenDocument)GetService(typeof(SVsUIShellOpenDocument));
    int result = openDoc.IsDocumentOpen(this, (uint)hNode.ID, hNode.Text, ref guidLogView, (uint)__VSIDOFLAGS.IDO_ActivateIfOpen,
            out outHierOwner, outHierItem, out editorFrame, out open);

    if (open != 1)
    {
        editorFrame = OpenEditor(hNode);
    }
    return editorFrame;
}

Now I want to call some public methods of the actual user control inside the editor. I also want to hook up with some events in case the editor control wants to send a message to tool window. Searching on google didn't help so I asked this basic question on MSDN VSX forum. The answer I got was quite cryptic but it worked.

private CtrlChatEditor GetChatEditorFromIVsWindowFrame(IVsWindowFrame editorFrame)
{
    if (editorFrame == null) return null;
    object objControl = null;

//the code to get the inner object
 int result = editorFrame.GetProperty((int)__VSFPROPID.VSFPROPID_DocView, out objControl);


if (result != VSConstants.S_OK) return null; VjEditorPane pane = objControl as VjEditorPane; if (pane == null) return null; CtrlChatEditor ctrlChatEditor = pane.Window as CtrlChatEditor; return ctrlChatEditor;//might be null }

Therefore my OpenEditor will look like this now.

private IVsWindowFrame OpenEditor(HierarchyTreeNode selectedItem)
{
    //HierarchyTreeNode selectedItem = ctrlToolWindow.GetItem(itemID);
    IVsUIShellOpenDocument openDoc = (IVsUIShellOpenDocument)GetService(typeof(SVsUIShellOpenDocument));
    IVsWindowFrame editorFrame;
    Guid guidEditorType = GuidList.guidEditorFactory;
    Guid guidLogView = VSConstants.LOGVIEWID.Primary_guid;
    IOleServiceProvider spContext = (IOleServiceProvider)GetService(typeof(IOleServiceProvider));
    string moniker = selectedItem.Text;

    int hr = openDoc.OpenSpecificEditor(0, moniker, ref guidEditorType, "",
        ref guidLogView, "Vj Editor - ", (IVsUIHierarchy)this, (uint)selectedItem.ID,
        IntPtr.Zero, spContext, out editorFrame);

    if (editorFrame != null)
    { editorFrame.Show(); 
//call public propreties and hooking up with the events. CtrlChatEditor ctrlChatEditor = GetChatEditorFromIVsWindowFrame(editorFrame); if (ctrlChatEditor != null) { ctrlChatEditor.OnMessageNeedToBeSend += CtrlChatEditor_OnMessageNeedToBeSend; ctrlChatEditor.ClientContact = selectedItem.ClientContact; ctrlChatEditor.BuddyContact = selectedItem.BuddyContact; } } return editorFrame;
}

Hope this will help someone.

 

Tags: ,

VsPackage 2010 | VSX

Powered by BlogEngine.NET 2.5.0.6
Original Design by Laptop Geek, Adapted by onesoft