Simple question - I found two ways to add a tool window to Visual Studio (2008): create an addin or create a package.
(Addin: http://www.codeproject.com/KB/dotnet/vstoolwindow.aspx)
(Package: http://msdn.microsoft.com/en-us/library/bb165051.aspx)
What's the "right" way?
You can do either, and I've done both. In some ways, addins are a bit easier, but they suffer from some annoying drawbacks.
Add-in:
+No requirement to install the Visual Studio SDK
+No requirement to use a Package Load Key (PLK) or sign your distributed binaries
+Easier development process when you use the Extensibility API (simplified code in many ways)
+Easier installation process (no wacky registry stuff)
-Doesn't seem to behave as well as VSPackage-based tool panes
-I've run into performance issues which prompted me to use the VS SDK COM interfaces instead of the Extensibility ones, leading to a significant performance bump. In other words, my "add-in" is now based on the VS SDK and is only really an add-in because it loads via an XML file instead of the registry. (Also, from everything I can tell, the Extensibility interfaces are just a large utility wrapper around the SDK.)
VSPackages:
+You can harness the full power of the VS SDK, both its feature set and (potentially, when carefully used) performance advantage
+Seems to behave more reliably than add-ins
-Requires signed binaries, a PLK, and a complicated installation procedure
-Steep learning curve, and many seemingly simple actions are nasty/convoluted. I now have an assembly providing extension methods to perform "obvious (to me)" actions on the COM interfaces. Between that and experience things have improved over time. There are similar options available to the community, which you should seriously consider if you go this route.
I think 280Z28 was perfectly correct prior VS2010. But now VS2010 and VS012:
Do not require officially signed packages (may only those that go to the Gallery have to);
Thanks to VSIX it can very easily install VSPackages that can also be deployed to the Gallery.
Moreover VS2010 supports another kind of extensibility: those are MEF extensions, that are lightweight plugins that trigger only at specific events of the IDE, like text editor events. An example is FixMixedTabs extension.
Just a create a VSPackage empty package (no menus, commands, ...) and copy this in the main class to create a VSPackage that basically loads when there's an active solution and just get a reference to the DTE2. In this way you can just use it as an Add-in.
// This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
// a package.
[PackageRegistration(UseManagedResourcesOnly = true)]
// This attribute is used to register the informations needed to show the this package
// in the Help/About dialog of Visual Studio.
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
[Guid(GuidList.guidVSPackage1PkgString)]
// Load this package when a solution is loaded (VSConstants.UICONTEXT_SolutionExists)
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
public sealed class VSPackage1Package : Package
{
/// <summary>
/// Default constructor of the package.
/// Inside this method you can place any initialization code that does not require
/// any Visual Studio service because at this point the package object is created but
/// not sited yet inside Visual Studio environment. The place to do all the other
/// initialization is the Initialize method.
/// </summary>
public VSPackage1Package()
{
Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
/// <summary>
/// Initialization of the package; this method is called right after the package is sited, so this is the place
/// where you can put all the initilaization code that rely on services provided by VisualStudio.
/// </summary>
protected override void Initialize()
{
Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
base.Initialize();
IVsExtensibility extensibility =
GetService(typeof(EnvDTE.IVsExtensibility)) as
IVsExtensibility;
DTE2 dte = extensibility.GetGlobalsObject(null).DTE as DTE2;
}
}
If you are just creating a simple tool window then I suggest going the Add-in route.
Both Packages and Add-Ins are ways of extending Visual Studio. Generally speaking they have the same functionality. Packages are a bit more powerful and allow deeper integration into Visual Studio. But that deeper integration comes with a cost including bigger ramp up times and installation procedures.
Add-ins are designed to be a more light weight extension mechanism. Smaller ramp up time and easier installation.
If all you are doing is tool window with basic interaction of the editor our code model then add-in is the best route.
Related
I find myself enabling and disabling the "Common Language Runtime Exceptions" checkbox in Exception Settings with considerable regularity. I'm tired of having to open the window every time. Is there a keyboard shortcut?
EDIT: as the answer as of June 2020 appears to be "no", I've requested a feature here: https://developercommunity.visualstudio.com/idea/1073035/keyboard-shortcut-to-enabledisable-the-common-runt.html
Is there a keyboard shortcut to enable/disable “Common Language
Runtime Exceptions” in Visual Studio exception settings?
I think there is no such quick shortcut to do that.
Actually, the shortcut for the Exception window is Ctrl+Alt+E, you can call such window by that.
However, VS only has a shortcut key to open a window, and there is no shortcut key to enable or disable an exception, and there are many different types of exceptions in the exception window. So it can be a bit difficult.
So you should use shortcut Ctrl+Alt+E to open Exception and then set the exception manually.
Besides, if you still want that feature to have a keyboard shortcut to enable/disable Common Language Runtime Exceptions, you can suggest this feature on our User Voice Forum.
After that, you can share the link with us here and anyone who is interested in this feature will vote it so that it will get more attention from Microsoft.
It is managed by the DebuggerServiceHelper class in VSDebugCoreUI.dll:
ExceptionSettingsBatchOperation{_operationDepth=3} DebuggerServiceHelper.BeginExceptionBatchOperation()
DebuggerServiceHelper.UpdateException(EXCEPTION_INFO150{bstrProgramName=null, bstrExceptionName="Common Language Runtime Exceptions", dwCode=0, dwState=16418})
ExceptionSettingsBatchOperation.EndBatchOperation()
But these are all internal classes and not easily accessible from external code.
Another approach is to find this WPF CheckBox on screen (by the TextBlock following it with the given Text property) and click it programmatically.
I really wish Exception Breaker worked for later versions of Visual Studio.
In combination with this answer to a similar question, I was able to get something to work. It is not ideal, but you might give this a try.
Note: I am using Visual Studio 2019
Tool required
The free version of the Visual Commander extension that allows Visual Studio macros in later versions.
Note: I tried (a little) to use the Macros for Visual Studio extension, but with no luck
Steps
Using Visual Commander, add a new command with the code below, save and compile.
Run with one of:
Run directly from the Visual Commander UI
Modify a toolbar and add the Extensions/Command01 command to it
Add a Keyboard shortcut via Options and select VCmd.Command01
Code
Notes:
I tried toggling the <All Common Language Runtime Exceptions not in this list> item, but did not have luck with it.
I tried looping through all of the Exceptions in the group but it was really slow (i.e. 15 seconds :-( ) so I picked the most important exceptions for my project.
I was unsuccessful finding a away to toggle the parent Common Language Runtime Exceptions, but if you find it, please leave a comment.
using EnvDTE;
using EnvDTE80; // DTE2 type
using EnvDTE90; // Debugger3
public class M : VisualCommanderExt.ICommand
{
public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
{
var lDebugger = DTE.Debugger as Debugger3;
var lExceptionSettings = lDebugger.ExceptionGroups.Item("Common Language Runtime Exceptions");
// Use this Exception as the master toggle
bool lExceptionsEnabledToSet = !lExceptionSettings.Item("System.ArgumentException").BreakWhenThrown;
// 2 examples
lExceptionSettings.SetBreakWhenThrown(lExceptionsEnabledToSet, lExceptionSettings.Item("System.ArgumentException"));
lExceptionSettings.SetBreakWhenThrown(lExceptionsEnabledToSet, lExceptionSettings.Item("System.OutOfMemoryException"));
// This does not work to set the whole group on/off:
//lExceptionSettings.SetBreakWhenThrown(true, lExceptionSettings.Item("<All Common Language Runtime Exceptions not in this list>"));
// This is really slow
//foreach (var lExceptionSetting in lExceptionSettings)
//{
// lExceptionSettings.SetBreakWhenThrown(lExceptionsEnabledToSet, lExceptionSetting as ExceptionSetting);
//}
}
}
I used the VS 2010 SDK to create and show a custom ToolWindowPane with a WPF control as content. I create a new instance and show it each time a Tool menu item is clicked (the ProvideToolWindow attribute has MultiInstances = true).
When the user attaches the debugger (e.g., hits F5 while in C# project) my ToolWindowPane suddenly hides. I'd like to make sure my tool window is always visible while open, no matter what context the user is in. Is there a way I can enforce that?
I've tried using the ProvideToolWindowVisibility attribute but that automatically shows a new instance of my tool window rather than keeping a remaining one open.
For VS 2010 SDK Microsoft added a new flag __VSCREATETOOLWIN2.CTW_fDocumentLikeTool
You can use this way:
public override void OnToolWindowCreated()
{
IVsWindowFrame windowFrame = Frame as IVsWindowFrame;
object varFlags;
windowFrame.GetProperty((int)__VSFPROPID.VSFPROPID_CreateToolWinFlags, out varFlags);
int flags = (int)varFlags | (int)__VSCREATETOOLWIN2.CTW_fDocumentLikeTool;
windowFrame.SetProperty((int)__VSFPROPID.VSFPROPID_CreateToolWinFlags, flags);
}
This way Tool Window persist open at "Document Well" when you go Debugging
However I have to say this give us some problems when debugging projects, avoiding us to open code files while debugging, like if Visual Studio document management was 'block', there are not so much information for this new flag...
So we preferred to hook to EnvDTE.DebuggerEvents and show the ToolWindow if hide when a debugging session start...
(our ToolWindow has MultiInstances = false)
Implement QueryShowTool
public:
int QueryShowTool(Guid % rguidPersistenceSlot, System::UInt32 dwId, [Runtime::InteropServices::Out] int % pfShowTool);
Enables the VSPackage to control whether to show or hide the tool
window. The shell calls this method when the user switches views or
contexts, for example Design, Debugging, Full Screen.
See https://learn.microsoft.com/en-us/visualstudio/extensibility/opening-a-dynamic-tool-window?view=vs-2017
Using C++/CLI, How to display a managed control (eg. System::Windows::Forms::Panel^) on a window created in native code?
An external program calls my native method where i can access it's window via
SubclassWindow(hNativeWindow, MyNativeWindowProc);
Then I create control with something similar to:
MyNameSpace::MyControl^ ctrl = osozKomunikator = gcnew MyControl("SomeText", hNativeWindow);
ctrl->Show();
MyControl is derived from System::Windows::Forms::UserControl and has overriden CreateParams to set Parent to hNativeWindow.
As the result the control flashes and dissapears, does not show at all or shows only after I slow down the execution with the debugger.
Please help.
Windows Forms supports being hosted like ActiveX in native windows since .Net 1.1. The host needs to implement some interfaces, though. MFC 8.0 wrapped around the necessary code in CWinFormsDialog and CWinFormsView. Use MFC's support classes if you can. If you can not, install MFC from Visual C++ 2005 or higher and check the source code of MFC's OLE support classes, like COleControlContainer, COleControlSite, etc.
I was wondering how Visual Studio associates MFC CDialog derived classes with their corresponding dialog resources. I'm not interested in how the connection is made at run time (as asked here), but rather at design time.
When I add a message handler to a dialog, how does it know which class to add the handler to.
Also, is it possible to have several CDialog derived classes associated with the same dialog resource and vice versa?
I have searched the project directory for the IDD_SOMEDIALOG string but have only found it in SomeDialog.h, resource.h and Project.rc in the expected places so I guess it somehow deduces the connection from those files, most likely the enum in SomeDialog.h:
// in class CSomeDialog:
enum { IDD = IDD_SOMEDIALOG };
I'm asking this mostly out of curiosity.
It depends on what version of dev studio.
In VS6 it was all kept in the CLW (Class Wizard File).
In newer versions of dev studio it doesn't use the CLW anymore and I don't know specifically how it knows, but i suspect its a live parsing instead of using a cached CLW.
As for having multiple derived dialogs using the same resource, it can be done manually. You can duplicate the created class files and rename them and remove the enum from header and edit the use of the IDD enum in the source file to be the actual dialog resource id (IDD_SOMEDIALOG).
AFAIK Dev Studio will only 'happily' handle one class to a dialog at a time. In my experience trying to re-use a dialog resource like this just ends up in a bit of battle with MFC & Dev Studio since they were not intended to do this.
To add to Ruddy's answer:
I noticed that some of my dialog classes in which I replaced the enum { IDD } with static const int IDD was not any longer associated with its dialog resource. Reverting to the enum re-associated them. So it seems that visual studio parses the source code to determine the relationships.
As for resource sharing, it would be ambiguous as to which class should receive the event handler code. Class sharing seems to be be impossible since it relies on the IDD which can not be assigned to a IDD_SOMETHING and IDD_SOMETHING_ELSE simultaneously.
In VB6, ActiveX DLL is listed as a project template but in VS 2005+ there is no such thing. Where is my good old ActiveX DLL template? Many thanks in advance.
A couple of concepts; .NET Assemblies are the functional equivalent to ActiveX DLLs in the .NET langauges. .NET Classes and method can be decorated with attribute that have various meaning in different context. A .NET Assembly can be turned into a ActiveX/COM DLL (or OCX) by using various attributes to assign the correct GUIDs.
A basic overview of setting a .NET assembly use COM is here.
Note that do google searches you should include VB6 .NET and COM (not ActiveX). COM generates more hits as it is the underlying technology behind the ActiveX term.
The MSDN article I linked shows a basic COM setup for a .NET Class. The attribute here is the ComClass Attribute.
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "6DB79AF2-F661-44AC-8458-62B06BFDD9E4"
Public Const InterfaceId As String = "EDED909C-9271-4670-BA32-109AE917B1D7"
Public Const EventsId As String = "17C731B8-CE61-4B5F-B114-10F3E46153AC"
#End Region
' A creatable COM class must have a Public Sub New()
' without parameters. Otherwise, the class will not be
' registered in the COM registry and cannot be created
' through CreateObject.
Public Sub New()
MyBase.New()
End Sub
End Class
There are other Attributes as well that are especially useful if you trying to subsitute a .NET assembly for an existing COM DLL or OCX. Finally .NET has a lot of different wizards that help you with the tedious details.
Try this: http://msmvps.com/blogs/pauldomag/archive/2006/08/16/107758.aspx
It outlines how to create an activex control and use it in a web page. As far as I know there's really no 'ActiveX' project template since .NET does it differently. However you can make your .Net controls visible to the COM world, which the article above illustrates.
It's not quite clear from you question, but if you want to be able to consume in VB6 (or some other com environment) something created in VS2005, you want to look at the Interop Forms Toolkit. This greatly simplifies interop between VB6 and VS2005. Now if you actually want to distribute those applications, installing what you created becomes a lot more fun (Hints: Don't use the GAC, install the .Net dll in the same directory as your application executable, and learn to use RegAsm.)
If you give a little description what you want to use the ActiveX.dll for (project library or User Control) and what environment you want to use it, more advice can be given.
I don’t know if this is what you are trying to do or not. But if you right click on the Toolbox in Visual Studio, in the popup menu select Choose Item…
When you get the “Choose Toolbox Item” dialog box come up, select the “COM Components” tab and check the COM Component(s) you want to add to the toolbox. I have done this to added the “Windows Media Player” to the toolbox and used it in a C# Winform.
From this dialog you can access any COM, OCX or ActiveX control loaded on you system.