locked
Can't set OLECMDTEXT in VS2012. RRS feed

  • Question

  • The following implementation taken from this list some time ago no longer seems to work in VS2012 for a dynamic command.  Works fine in VS2010/2008/2005.

    public static void SetText(IntPtr pCmdTextInt, string text)
    {
    	Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT pCmdText = (Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT)Marshal.PtrToStructure(pCmdTextInt, typeof(Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT));
    	var menuText = text.ToCharArray();
    	// Get the offset to the rgsz param.  This is where we will stuff our text
    	//
    	IntPtr offset = Marshal.OffsetOf(typeof(Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT), "rgwz");
    	IntPtr offsetToCwActual = Marshal.OffsetOf(typeof(Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT), "cwActual");
    
    	// The max chars we copy is our string, or one less than the buffer size,
    	// since we need a null at the end.
    	//
    	int maxChars = Math.Min((int)pCmdText.cwBuf - 1, menuText.Length);
    
    	Marshal.Copy(menuText, 0, (IntPtr)((long)pCmdTextInt + (long)offset), maxChars);
    
    	// append a null character
    	Marshal.WriteInt16((IntPtr)((long)pCmdTextInt + (long)offset + maxChars * 2), 0);
    
    	// write out the length
    	// +1 for the null char
    	Marshal.WriteInt32((IntPtr)((long)pCmdTextInt + (long)offsetToCwActual), maxChars + 1);
    			}
    

    The declaration of the command in the .vsct file is as follows:

    			<Menu guid="guidMyCmdSet" id="IDMX_MY_MENU" priority="0x0150" type="Menu">
    				<Parent guid="guidMyCmdSet" id="IDG_CTX_MY_NODE"/>
    				<CommandFlag>DefaultInvisible</CommandFlag>
    				<CommandFlag>DynamicVisibility</CommandFlag>
    				<Strings>
    					<ButtonText>MyButtonText</ButtonText>
    					<CommandName>MyCommandName</CommandName>
    				</Strings>
    			</Menu>
    

    Thursday, April 11, 2013 6:14 PM

Answers

  • I am surprised that ever worked. If items aren't tagged TextChanges then we basically never ask for the text (you shouldn't see the OLECMDTEXT structure with the OLECMDTEXTF_NAME flag in its cmdtextf field) nor do we ever copy any text returned.

    Also you don't need the CommandName, that is a stupid tag that the wizard used to put in there but it only has any influence on how the item is displayed in the customization dialog, which is not what most people assume/expect.
    Thursday, April 11, 2013 6:25 PM

All replies

  • I am surprised that ever worked. If items aren't tagged TextChanges then we basically never ask for the text (you shouldn't see the OLECMDTEXT structure with the OLECMDTEXTF_NAME flag in its cmdtextf field) nor do we ever copy any text returned.

    Also you don't need the CommandName, that is a stupid tag that the wizard used to put in there but it only has any influence on how the item is displayed in the customization dialog, which is not what most people assume/expect.
    Thursday, April 11, 2013 6:25 PM
  • Thanks Ryan.  Adding the TextChanges flag did the trick.  It is weird it's worked for so long, but this has been in our product forever.  I did leave out one <CommandFlag> as I was trying to sanitize my code sample, at that's the DynamicItemStart flag.  Maybe that was enough to cause the query for new text in prior versions.  But, TextChanges in addition to DynamicItemStart now seem to be required.
    Thursday, April 11, 2013 6:45 PM
  • I do vaguely recall seeing something like that, or hearing about a bug like that, where DynamicItemStart used to actually 'imply' text changes, but I don't believe it was documented, so it was more of a happy coincidence.  Also, the VSCT you showed couldn't be the one for the actual command, since a menu can't be tagged DynamicItemStart. Well, it can't be, but it won't result in anything.
    Thursday, April 11, 2013 7:38 PM