Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Visual Studio.NET / Extensibility / May 2006

Tip: Looking for answers? Try searching our database.

Finding a CommandBar Uniquely

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Rick Strahl (MVP) - 17 May 2006 02:10 GMT
Hi all,

I'm still struggling with the problem of trying to retrieve a specific
commandbar that is a Context menu. The problem specifically is that there
are SEVERAL  command bars named "Context" and using:

CommandBars["Context"]

is not likely to return the correct one.

Is there a better way to uniquely identify a Context menu where there's no
menu hierarchy to specifically walk down to the correct CommandBar?

There's gotta be SOME way to get a UNIQUE reference to the CommandBar?

Anybody have any ideas?

TIA,

+++ Rick ---

Signature

Rick Strahl
West Wind Technologies
www.west-wind.com
www.west-wind.com/weblog

Carlos J. Quintero [VB MVP] - 17 May 2006 11:14 GMT
Hi Rick,

See the answer by Ed Dore [MSFT] in the thread "Enterprise Templates
Properties and commandbars problem" in this same newsgroup on April 25. You
can retrieve a command bar by GUID/Id instead of by name.

Signature

Best regards,

Carlos J. Quintero

MZ-Tools: Productivity add-ins for Visual Studio
You can code, design and document much faster:
http://www.mztools.com

> Hi all,
>
[quoted text clipped - 16 lines]
>
> +++ Rick ---
Rick Strahl (MVP) - 17 May 2006 21:54 GMT
Hi Carlos,

Can you be a little more specific? There's a lot of unrelated stuff in that
thread.

I'm already using a routine to find the command bar - I know have the right
bar in the search routine, but I can't get it to reference that bar in the
startup code using either the CommandBar indexer or FindControl. I've tried
using the Id of the commandbar but that doesn't work either as the indexer
or using FindControl.

You say use the Guid - how do I find the Guid? And then how do I use it to
read the CommandBar? Indexer? FindControl?

This doesn't work at all:

ContextBar = bars.FindControl(Missing.Value /*MsoBarType.msoBarTypePopup*/,
Missing.Value,"Context",Missing.Value);

and this:
ContextBar = bars["Context"]

finds only the first instance which is typically the wrong one.

What is the right way to reference a CommandBar with an ID or Guid and where
does the Guid come from (which property - i don't see it on the CommandBar
instance. I see an int Id which I've tried with no success using FindControl
and also by passing it as the indexer. Both fail.

Signature

Rick Strahl
West Wind Technologies
www.west-wind.com
www.west-wind.com/weblog

> Hi Rick,
>
[quoted text clipped - 22 lines]
>>
>> +++ Rick ---
Carlos J. Quintero [VB MVP] - 18 May 2006 09:43 GMT
Hi Rick,

I was referring to the post where Ed talks about using
IVsProfferCommands::FindCommandBar to find a command bar by Guid/Id. The
problem is that we don´t know the Guid of that toolbar so you have to either
ask some MS tech (maybe Ed can look it for you) or get some document in the
SDK that lists the command bar guids (not sure if such thing exists,
though). Or maybe the SDK provides a way to get the Guid of a commandbar if
you have its name...

Signature

Best regards,

Carlos J. Quintero

MZ-Tools: Productivity add-ins for Visual Studio
You can code, design and document much faster:
http://www.mztools.com

> Hi Carlos,
>
[quoted text clipped - 51 lines]
>>>
>>> +++ Rick ---
"Ed Dore [MSFT]" - 19 May 2006 00:19 GMT
Hi Rick,

If you can identify the particular context menu you're interested in, I'll
see if I can track down the guid:id pair the identifies the commandbar.
Note this technique really only works if the commandbar in question was
implemented by a package (ala Visual Studio SDK). The guid:id pair that
identifies a particular command (or commandbar) it typically defined in the
package's embedded command table resource (.CTO file).

This particular problem, of being able to uniquely identify a commandbar
from the DTE automation model, is well know to our developers, and they are
currently looking into ways to address this in future releases.

Sadly, there is no complete list of guid:id pairs for the hundreds of
command and toolbars implemented across the various products integrated
into the VS IDE. The .CTC and .H files in the Visual Studio SDK, do contain
a good number, but many have not been published, nor likely will be.

So if you have a particular context menu you're interested in, just post
here (or the MSDN Extensibility Forum) and we'll try to provide the info
for you.

Sincerely,
Ed Dore [MSFT]

This post is 'AS IS' with no warranties, and confers no rights.
Rick Strahl (MVP) - 20 May 2006 03:24 GMT
Hi Ed,

The menu I'm interested in is the one that pops up in the ASP.NET designer
when you are on a table cell. I've got everything else working except this
one.

The menu Id (don't know if this helps) is: 33103

On the menu are:

Context  33103 System.__ComObject

     Cu&t - 21

     Cop&y - 19

     &Paste - 22

     Past&e Alternate - 746

     &Delete - 478

     &Style... - 746

     &Insert - 32768

     De&lete - 32768

     &Select - 32768

     &Resize - 32768

     &Merge Cells - 798

     Run As Ser&ver Control - 746

     View &Code - 746

     View Component Des&igner - 746

     View in &Browser - 393219

     Edit &Master - 746

     Add Co&ntent Page - 10944558

     Show Smart Ta&g - 746

     WebForms Designer Verbs - 746

     Ed&it Template - 32768

     E&nd Template Editing - 746

     P&roperties - 393246

Assuming you can find this mystical Id <g>, how do I reference then? Through
the CommandBars indexer?

I did make this work with a hack for a workaround:

               CommandBar contextBar = bars[contextMenuName] as CommandBar;

               // *** Get the general Context bar - need to hook that as
well

               CommandBar designerBar = bars["Context"] as CommandBar;

               // *** Get the Cell Context menu

               CommandBar cellBar = null;

               foreach (CommandBar Bar in bars)

               {

                   if (Bar.Name == "Context" && Bar.Id == 33103)

                   {

                       cellBar = Bar;

                       break;

                   }

               }

That works locally here, but I suspect that the ID isn't actually unique and
it probably won't work on other people's machines or locales.

I definitely would like a more reliable and less resource intensive way of
doing this.

+++ Rick ---

Signature

Rick Strahl
West Wind Technologies
www.west-wind.com
www.west-wind.com/weblog

> Hi Rick,
>
[quoted text clipped - 25 lines]
>
> This post is 'AS IS' with no warranties, and confers no rights.
"Ed Dore [MSFT]" - 26 May 2006 19:07 GMT
Hi Rick,

I apologize for the late response. Things have been a bit busy around here
lately. You're suspicions are correct. There isn't a 100%

guarantee that you're going to get the right context menu in this instance.
At least not with the DTE automation interfaces.

As I mentioned in that earlier post Carlos mentioned, the DTE automation
model does allow for keying off the CommandBar name, but

those names are not unique. Using the CmdBrowser addin sample from

http://www.microsoft.com/downloads/details.aspx?FamilyId=79C7E038-8768-4E1E-
87AE-5BBBE3886DE8&displaylang=en, and you'll see multiple

commandbars with the same name. This is a known problem that the dev team
is working on correcting in some fashion for the next

release. But currently, we're stuck having to find all the CommandBars and
then guess which one is the right one based on the

commands it contains. And that isn't necessarily an exact mechanism for
retrieving the particular CommandBar you're looking for.

Especially given that people can reconfigure the commandbars.

The context menu you mentioned in your last post is actually implemented by
the HTML Editor package and is defined in that package's

embedded .CTO resource with the following guid:id pair:

  {D7E8C5E1-BDB8-11D0-9C88-0000F8040A53}:49

The only way to retrieve the menu (aka CommandBar) by way of this unique
identifier is with the IVsProfferCommands.FindCommandBar

method. You can retrieve this interface from your addin by way of code
similar to the following:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

using Extensibility;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.CommandBars;

// note, you need to reference the Microsoft.VisualStudio.OLE.Interop.dll
// assembly, which contains the IServiceProvider we need to Query for the
// IVsProfferCommands service.
using IOleServiceProvider =
Microsoft.VisualStudio.OLE.Interop.IServiceProvider;

namespace GetCmdBar
{
  public class Connect : IDTExtensibility2
  {
     public Connect()
     {
     }

     public void OnConnection(object app, ext_ConnectMode mode, object
inst, ref Array custom)
     {
        _applicationObject = (DTE2)app;
        _addInInstance = (AddIn)inst;

        // retrieve IVsProfferComands via DTE's IServiceProvider
        IOleServiceProvider sp = (IOleServiceProvider)app;
        Guid guidSvc = new
Guid(typeof(IVsProfferCommands).GUID.ToString());
        IntPtr service;
        sp.QueryService(ref guidSvc, ref guidSvc, out service);
        IVsProfferCommands vsProfferCmds =
(IVsProfferCommands)Marshal.GetObjectForIUnknown(service);
        Marshal.Release(service);

        // retrieve the specific command bar we're looking for
        // (CMDSETID_HtmEdGrp:IDMX_HTM_DESIGN_TABLE)
        Guid guidCmdGroup = new
Guid("{D7E8C5E1-BDB8-11D0-9C88-0000F8040A53}");
        uint menuID = 49;

        CommandBar cmdBarTableContext =
(CommandBar)vsProfferCmds.FindCommandBar(IntPtr.Zero, ref guidCmdGroup,
menuID);
        Debug.WriteLine(cmdBarTableContext.Name);
     }

     public void OnDisconnection(ext_DisconnectMode disconnectMode, ref
Array custom) {}
     public void OnAddInsUpdate(ref Array custom) {}
     public void OnStartupComplete(ref Array custom) {}
     public void OnBeginShutdown(ref Array custom) {}
       
     private DTE2 _applicationObject;
     private AddIn _addInInstance;
  }
}

As a side note with respect to identifying the guid:id pair that a package
uses to create it's commandbars. Paul Harrington came up

novel way to help identify the guid:id pair by way of the IDE's Export
Settings feature. Martin Tracy's recently blogged about this

techinque at
http://blogs.msdn.com/martintracy/archive/2006/05/23/604927.aspx.
Hopefully, we'll have an even better solution come VS

2005 SP1, and Orcas, by way of a simple logging feature Paul enabled in the
core IDE sources a couple weeks back.

Sincerely,
Ed Dore [MSFT]

This post is 'AS IS' with no warranties, and confers no rights.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.