Custom command in custom toolbar not working

3110
8
08-11-2010 09:11 AM
MatthewBuchanan
New Contributor III
I am having trouble with creating custom toolbars with custom command buttons in Visual Studio 2005. I'm using ArcGIS 9.3.1. The button is replaced by a circle with a red line through it and the text [Missing]

All the projects that I try to create, even a sample toolbar from EDN doesn't work (it is an older version, but it should still work)
http://edndoc.esri.com/arcobjects/9.0/Samples/Developer_Guide_Scenarios/ArcGIS_Desktop/Developer_Sce...

Not sure if I should be concerned about these messages I get in the immediate window:
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
ArcMap.exe Error: 0 : SetCompatibleTextRenderingDefault must be called before the first IWin32Window object is created in the application.
   at System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(Boolean defaultValue)
   at XToolsNavigator.Toolbar.XToolsApplication.InitVisualApplicationSettings()
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
ArcMap.exe Error: 0 : Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at ESRI.ArcGIS.Framework.ICommandBars.Find(Object identifier, Boolean noRecurse, Boolean noCreate)
   at MetadataEditor.Toolbar.ArcMapUIElementsFactory.GetObjectByUID(String uid)
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
0 Kudos
8 Replies
BradChappell
New Contributor
Did you add the license control to your form?
0 Kudos
NeilClemmons
Regular Contributor III
Do your command classes have the proper ESRI component registration code in them?  It looks like ArcMap is not able to find your command classes, which could be a sign that they aren't registered with ArcMap.
0 Kudos
NathanAmboy
New Contributor
Neil, could you please be more specific?   How do we check the component registration?  I too hit this same problem yesterday - using 9.3 and VS 2008.  I'm building a very simple form to load the feature classes from the TOC.  My code has no errors till I compile.
0 Kudos
MatthewBuchanan
New Contributor III
My colleague runs the same sample code from the EDN site and does not have the same error messages that I have.
The only difference is that he is running Windows XP 32 bit and I'm running 64 bit version.

We are both running 9.3.1 SP2 Build 4000.

I'll post some more code..
0 Kudos
MatthewBuchanan
New Contributor III
The code of the EDN sample is downloadable from the link in my first post. This is the code for my own toolbar and command.

This is the code for my toolbar.
Matthew_Toolbar.vb

Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports System.Runtime.InteropServices

<ComClass(Matthew_Toolbar.ClassId, Matthew_Toolbar.InterfaceId, Matthew_Toolbar.EventsId), _
 ProgId("DamMaker2_New.Matthew_Toolbar")> _
Public NotInheritable Class Matthew_Toolbar
    Inherits BaseToolbar

#Region "COM Registration Function(s)"
    <ComRegisterFunction(), ComVisibleAttribute(False)> _
    Public Shared Sub RegisterFunction(ByVal registerType As Type)
        ' Required for ArcGIS Component Category Registrar support
        ArcGISCategoryRegistration(registerType)

        'Add any COM registration code after the ArcGISCategoryRegistration() call

    End Sub

    <ComUnregisterFunction(), ComVisibleAttribute(False)> _
    Public Shared Sub UnregisterFunction(ByVal registerType As Type)
        ' Required for ArcGIS Component Category Registrar support
        ArcGISCategoryUnregistration(registerType)

        'Add any COM unregistration code after the ArcGISCategoryUnregistration() call

    End Sub

#Region "ArcGIS Component Category Registrar generated code"
    ''' <summary>
    ''' Required method for ArcGIS Component Category registration -
    ''' Do not modify the contents of this method with the code editor.
    ''' </summary>
    Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        MxCommandBars.Register(regKey)

    End Sub
    ''' <summary>
    ''' Required method for ArcGIS Component Category unregistration -
    ''' Do not modify the contents of this method with the code editor.
    ''' </summary>
    Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        MxCommandBars.Unregister(regKey)

    End Sub

#End Region
#End Region

#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 = "a7fdf8e2-1875-4039-bb95-4eb593320f6b"
    Public Const InterfaceId As String = "e84e68bc-5968-4285-9c2b-708a533867a0"
    Public Const EventsId As String = "a1c8d3fc-91e8-43cb-8f6f-798a6b738cfd"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()

        '
        'TODO: Define your toolbar here by adding items
        AddItem("esriArcMapUI.ZoomInFixedCommand")
        AddItem("esriArcMapUI.ZoomOutTool")
        BeginGroup() 'Separator
        ' Today these buttons are showing up! but the command associated doesn't work properly.
        AddItem("DamMaker2_New.tool_DigitizeLine") 'try 1
        AddItem("{80414059-5b90-44a6-bce9-3aeceea1f58a}") ' try 2
        BeginGroup() 'Separator
        AddItem("{FBF8C3FB-0480-11D2-8D21-080009EE4E51}", 1) 'undo command
        AddItem(New Guid("FBF8C3FB-0480-11D2-8D21-080009EE4E51"), 2) 'redo command
    End Sub

    Public Overrides ReadOnly Property Caption() As String
        Get
            'TODO: Replace bar caption
            Return "BGC DamMaker2 New"
        End Get
    End Property

    Public Overrides ReadOnly Property Name() As String
        Get
            'TODO: Replace bar ID
            Return "Matthew_Toolbar"
        End Get
    End Property
End Class


This is my command button which digitizes a line.
tool_DigitizeLine.vb


Imports System.Runtime.InteropServices
Imports System.Drawing
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Geometry
Imports System.Windows.Forms

<ComClass(tool_DigitizeLine.ClassId, tool_DigitizeLine.InterfaceId, tool_DigitizeLine.EventsId), _
 ProgId("DamMaker2_New.tool_DigitizeLine")> _
Public NotInheritable Class tool_DigitizeLine
    Inherits BaseTool

#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 = "80414059-5b90-44a6-bce9-3aeceea1f58a"
    Public Const InterfaceId As String = "fd639bd1-19df-4080-a2b8-a79ec0cb8071"
    Public Const EventsId As String = "b6256c63-eecd-403a-a0a9-8695bb16021e"
#End Region

#Region "COM Registration Function(s)"
    <ComRegisterFunction(), ComVisibleAttribute(False)> _
    Public Shared Sub RegisterFunction(ByVal registerType As Type)
        ' Required for ArcGIS Component Category Registrar support
        ArcGISCategoryRegistration(registerType)

        'Add any COM registration code after the ArcGISCategoryRegistration() call

    End Sub

    <ComUnregisterFunction(), ComVisibleAttribute(False)> _
    Public Shared Sub UnregisterFunction(ByVal registerType As Type)
        ' Required for ArcGIS Component Category Registrar support
        ArcGISCategoryUnregistration(registerType)

        'Add any COM unregistration code after the ArcGISCategoryUnregistration() call

    End Sub

#Region "ArcGIS Component Category Registrar generated code"
    Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        MxCommands.Register(regKey)

    End Sub
    Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        MxCommands.Unregister(regKey)

    End Sub

#End Region
#End Region

    Private m_application As IApplication
    Private m_strWorkingPath As String

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()

        ' TODO: Define values for the public properties
        ' TODO: Define values for the public properties
        MyBase.m_category = "BGC DamMaker2New"  'localizable text 
        MyBase.m_caption = "digitize a line"   'localizable text 
        MyBase.m_message = "please work!!!"   'localizable text 
        MyBase.m_toolTip = "doh!" 'localizable text 
        MyBase.m_name = "DamMaker2New_ScoobyDoo"  'unique id, non-localizable (e.g. "MyCategory_ArcMapTool")

        Try
            'TODO: change resource name if necessary
            Dim bitmapResourceName As String = Me.GetType().Name + ".bmp"
            MyBase.m_bitmap = New Bitmap(Me.GetType(), bitmapResourceName)
            MyBase.m_cursor = New System.Windows.Forms.Cursor(Me.GetType(), Me.GetType().Name + ".cur")
        Catch ex As Exception
            System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap")
        End Try
    End Sub

    Public Overrides Sub OnCreate(ByVal hook As Object)
        If Not hook Is Nothing Then
            m_application = CType(hook, IApplication)

            'Disable if it is not ArcMap
            If TypeOf hook Is IMxApplication Then
                MyBase.m_enabled = True
            Else
                MyBase.m_enabled = False
            End If
        End If

        ' TODO:  Add other initialization code
    End Sub

    Public Overrides Sub OnClick()
        'TODO: Add tool_DigitizeLine.OnClick implementation
        MsgBox("Please digitize a dam centre line now." & vbCrLf & "Make sure it doesn't go beyond the edges of your DEM." & _
                vbCrLf & "Start line from the left bank (facing downstream)" & vbCrLf & "(left side of line is downstream)" & _
                vbCrLf & "If the selected shapefile exists, it will be deleted", , "BGC DamMaker2")
    End Sub

    Public Overrides Sub OnMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)
        'TODO: Add tool_DigitizeLine.OnMouseDown implementation
        'MsgBox("now you can digitize")
        Dim mxdocument As IMxDocument = m_application.Document
        ' Get mxDocument from modTools function GetMxDocument
        'Dim mxDocument As IMxDocument = GetMxDocument(m_application)
        DigitizeLine(MxDocument)
    End Sub

    Public Overrides Sub OnMouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)
        'TODO: Add tool_DigitizeLine.OnMouseMove implementation
    End Sub

    Public Overrides Sub OnMouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)
        'TODO: Add tool_DigitizeLine.OnMouseUp implementation
    End Sub
End Class


I can't attach the whole code because the editor complained that it was too long.
There is another Sub in the tool_DigitizeLine.vb module that does the actual work, and it calls some functions in a modTools.vb code module. They are attached in a zip file.
0 Kudos
MatthewBuchanan
New Contributor III
It turns out that the error I was getting in the immediate window had nothing to do with why my code wasn't working. I went through my code line by line and cleaned it out. By adding Try, Catch blocks I was able to isolate the problem. ESRI Canada tech support helped me out.

ArcMap.exe Error: 0 : SetCompatibleTextRenderingDefault must be called before the first IWin32Window object is created in the application.
   at System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(Boolean defaultValue)
   at XToolsNavigator.Toolbar.XToolsApplication.InitVisualApplicationSettings()


I am still getting these error messages in the Immediate window when running my project in Debug mode, but it doesn't seem to stop the code from working properly. I do get error messages when I exit ArcMap sometimes even when I'm not in Debug mode, so it may have something to do with my system.
0 Kudos
vincentLahaye
New Contributor II
Hi,

be sure you compile your code with x86 propertie and not Any CPU propertie.  You need this to run your application on a 64 bit machine.

Vincent
0 Kudos
MatthewBuchanan
New Contributor III
Under Project Properties, Compile, Advanced Compile Options
Target CPU:
x86

- I still get the same Immediate window messages on my x64 machine

When I change to
Target CPU:
x64

I get these errors and warnings:
Error 1 File "C:\TOOLS\Visual Studio 2005\Projects\DamMaker2_New\bin\Release\DamMaker2_New.dll" is not a valid assembly. DamMaker2_New
Warning 2 Possible problem detected while building assembly 'DamMaker2_New': Referenced assembly 'mscorlib.dll' targets a different processor
Warning 3 Possible problem detected while building assembly 'DamMaker2_New': Referenced assembly 'System.Data.dll' targets a different processor

Since ArcMap is a 32 bit program, do I need to use a 32 bit OS to compile Visual Studio projects for ArcMap?
0 Kudos