Windows Develop Bookmark and Share   
 index > Windows Forms Designer > VS.NET Toolbar
 

VS.NET Toolbar

I've created a VS.NET Add-in, pretty easy, but is there an easy way to create a VS.NET Toolbar?  Is it even possible?  Thanx
MigrationUser 1  Tuesday, February 04, 2003 11:53 PM
It is possible but it requires that you purchase the VSIP SDK.  This is an SDK that allows you to plug in very deeply into Visual Studio.NET.  However, it doesn't come cheap (or simple!).  It's typically sold to language vendors who want to write their own project systems, debuggers, etc.
MigrationUser 1  Thursday, February 06, 2003 5:26 PM
Can it be sold to entrepreneurs?  ;)  Got any info on it?
MigrationUser 1  Thursday, February 06, 2003 5:33 PM
Nevermind, found it...

<a href="http://msdn.microsoft.com/vstudio/vsip/default.asp">Visual Studio .NET Integration Program</a>
MigrationUser 1  Thursday, February 06, 2003 6:26 PM
You dont need VSIP. Here is some code I used in a macro to create toolbars. I think you can do the same in an add-in. It should not be hard to convert to C#, if you need to (macros only support VB). There is a yahoo group for VS.net add-ins. I think the bug with removing the old toolbar would not exist in an add-in.

The main diff with an add-in: here all the command names are in fact function names in a macro module. I think there is a way to expose the add-in functions as commands without writing stub macros, but I am not sure. Seems stupid if MS allowed macros to generate commands, but not add-ins. I don't have experience with add-ins, but I think in the yahoo group they spoke of toolbars, so there must be a way.

    Sub aaAddToolbarAndButtons()
        Dim commandBar As CommandBar
        Dim cmds As Commands

        cmds = DTE.Commands
        ' Create a toolbar if it does not exist
        ' Unfortunately, catch does not work, nor the is condition, so there is no way to tell
        'Try
        '    commandBar = DTE.CommandBars("Editing Macros")
        'Catch e As System.Exception
        'End Try
        'If Not commandBar Is GetType(CommandBar) Then
        commandBar = cmds.AddCommandBar("Editing Macros", vsCommandBarType.vsCommandBarTypeToolbar)
        'End If
        Dim menu As CommandBar

        menu = cmds.AddCommandBar("etc", vsCommandBarType.vsCommandBarTypeMenu, commandBar)
        AddToolbarButton(menu, "TypeDouble", "double")
        AddToolbarButton(menu, "TypeFloat", "float")
        AddToolbarButton(menu, "TypeInt", "int")
        AddToolbarButton(menu, "TypeBool", "bool")
        AddToolbarButton(menu, "TypeString", "string")
        AddToolbarButton(menu, "TypeObject", "object")
        AddToolbarButton(menu, "TypeVoid", "void")
        AddToolbarButton(menu, "LiteralThis", "this")
        AddToolbarButton(menu, "LiteralString", """""")
        AddToolbarButton(menu, "LiteralNull", "null")
        ' a lot more menus added here ...
    End Sub

    Private Sub AddToolbarButton(ByVal commandBar As CommandBar, ByVal macroName As String, ByVal caption As String)
        Dim cmds As Commands
        Dim ctl As CommandBarControl
        cmds = DTE.Commands
        ctl = cmds.Item("Macros.Frank.Editing." & macroName).AddControl(commandBar)
        ctl.Caption = caption
        ctl.TooltipText = macroName
    End Sub

    Sub aaRemoveToolbar()
        Dim cmds As Commands
        Dim cmdbar As CommandBar
        cmds = DTE.Commands
        cmdbar = DTE.CommandBars("Editing Macros")
        cmds.RemoveCommandBar(cmdbar)
    End Sub

MigrationUser 1  Friday, February 07, 2003 1:20 PM
cool, thanx a lot, i'll give it a go.  It's fine that it's in VB, that's what i usually use anyway  ;) 

the other part of this project though involves navigating around in VS.NET and putting code where the cursor is, etc...i'm guessing i won't be able to do that without VSIP though  :( 
MigrationUser 1  Friday, February 07, 2003 1:24 PM
It is possible to navigate through the code and insert text using the EnvDTE namespace. First you have to find the designer host for the doc. Here is a class I created for injecting a member -- it is only a test, I never used it. You have to paste into a .cs file to get the formatting back.

internal class CodeInjector
{
public static void InsertCode(DTE dte, IDesignerHost host, string code)
{
Document ourDoc = FindOurDocument(dte, host);
//OpenCodeDoc(dte, ourDoc);// may not be necessary
// find our class
string className = host.RootComponentClassName;
FileCodeModel cm = ourDoc.ProjectItem.FileCodeModel;
CodeClass cc = null;
foreach (CodeElement ce in cm.CodeElements)
{
cc = FindClass(ce, className);
if (cc != null)
break;
}
if (cc != null)
{
// first create codedom
CodeCommentStatement comment = new CodeCommentStatement(code);
// cannot generate code from a method -- have to use a type, or
// hope the method is already there
//CodeMemberMethod method = new CodeMemberMethod();
//method.Name = "test";
//method.Comments.Add(comment);

// generate a string from the codedom
CodeDomProvider provider;
if (ourDoc.Language == "CSharp")
provider = new Microsoft.CSharp.CSharpCodeProvider();
// TODO: need to test this -- don't know which string to use
else if (ourDoc.Language == "VB")
provider = new Microsoft.VisualBasic.VBCodeProvider();
else
return;
ICodeGenerator generator = provider.CreateGenerator();
StringBuilder sb = new StringBuilder();
TextWriter writer = new IndentedTextWriter(new StringWriter(sb));
generator.GenerateCodeFromStatement(comment, writer, null);
writer.Flush();

// if the method already exists, delete body
EditPoint start = null;
foreach (CodeElement ce in cc.Members)
{
CodeFunction cf = ce as CodeFunction;
if (cf != null && cf.Name == "test")
{
start  = cf.StartPoint.CreateEditPoint();
start.LineDown(2);
start.StartOfLine();
EditPoint end  = cf.EndPoint.CreateEditPoint();
end.LineUp(1);
end.EndOfLine();
start.Delete(end);
break;
}
}

if (start == null)
{
if (ourDoc.Language == "CSharp")
{
CodeFunction cf = cc.AddFunction("test", vsCMFunction.vsCMFunctionFunction,
vsCMTypeRef.vsCMTypeRefInt, -1, vsCMAccess.vsCMAccessPrivate, null);
start = cf.StartPoint.CreateEditPoint();
start.LineDown(2);
start.StartOfLine();
}
else
{
// TODO: here error message
}
}

// insert the string into the function
start.Insert(sb.ToString());
}
}

private static CodeClass FindClass(CodeElement root, string className)
{
CodeClass cc = root as CodeClass;
if (cc != null)
{
if (cc.FullName == className)
return cc;
foreach (CodeElement ce in cc.Members)
{
if (ce is EnvDTE.CodeNamespace || ce is CodeClass)
{
cc = FindClass(ce, className);
if (cc != null)
return cc;
}
}
}
else
{
EnvDTE.CodeNamespace cn = root as EnvDTE.CodeNamespace;
if (cn != null)
{
foreach (CodeElement ce in cn.Members)
{
if (ce is EnvDTE.CodeNamespace || ce is CodeClass)
{
cc = FindClass(ce, className);
if (cc != null)
return cc;
}
}
}
}
return null;
}

private static Document FindOurDocument(DTE dte, IDesignerHost host)
{
foreach (Document doc in dte.Documents)
{
if (doc.Kind != Constants.vsDocumentKindText)
continue;
foreach (Window window in doc.Windows)
{
// right now, hook to all -- later only certain ones?
IDesignerHost windowHost = window.Object as IDesignerHost;
if (windowHost != null && windowHost == host)
return doc;
}
}
return null;
}

private static void OpenCodeDoc(DTE dte, Document document)
{
bool codeOpen = dte.get_IsOpenFile(Constants.vsViewKindCode, document.FullName);
if (!codeOpen)
{
ItemOperations ItemOp = dte.ItemOperations;
ItemOp.OpenFile(document.FullName, Constants.vsViewKindCode);
}
}
}
MigrationUser 1  Friday, February 07, 2003 10:38 PM
awesome!  thanx so much!  I'm actually on my way out of town, but when I get back, I will definitely be giving that a try...thanx again  :) 
MigrationUser 1  Saturday, February 08, 2003 11:39 PM

You can use google to search for other answers

Custom Search

More Threads

• Drag and drop doesn't works on design surface
• VS form designer eats up lots of disk space...
• How to register an activex control
• Sort out on date to verifier that it is indeed a value dates VB.NET?
• Creating Events in C#
• Convert projects to using new FormXXX.Designer.cs format
• Windows Forms Editor
• VS2008/VB: Dam* forms designer corrupted again! DataMember property not found! Whyyyyyy?
• problem displaying childform
• Why doesn't the myCollection property show in run time?