Search code examples
c++-climenuitem

Cannot cast from System::Object to System::Windows::Forms::MenuItem in C++/CLI


I'm working on my C++/CLI project as I'm adding the sub menu items with click event. I'm having a problem with getting the text of the menu item, because when I try this:

Debug::WriteLine("SmtpEmail............" + sender);

I'm getting this as the return output:

System.Windows.Forms.MenuItem, Items.Count: 0, Text: hello

So I will have to convert from a string to system menu item.

When I try this:

MenuItem^ selectedItem = (MenuItem)sender;
Debug::WriteLine("SmtpEmail............" + selectedItem.Text->ToString());

I'm getting an error:

'type cast' : cannot convert from 'System::Object ^' to 'System::Windows::Forms::MenuItem'

The error are jumping on this line:

MenuItem^ selectedItem = (MenuItem)sender;

It said that I cannot convert from 'System::Object ^' to 'System::Windows::Forms::MenuItem'.

Here is the full code:

   private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
         RegistryKey^ rkCurrentUser = Registry::CurrentUser;
         RegistryKey^ rkInternetAccountManager = rkCurrentUser->OpenSubKey("Software\\Microsoft\\Internet Account Manager\\Accounts");

         
         for each (String^ getkeysNames in rkInternetAccountManager->GetSubKeyNames()) {
             if (getkeysNames->Contains("0000000")) {
                 RegistryKey^ myKey = rkCurrentUser->OpenSubKey("Software\\Microsoft\\Internet Account Manager\\Accounts\\"+getkeysNames->ToString());
                     
                 String^ AccountName = myKey->GetValue("Account Name")->ToString();
                 String^ POP3Server = myKey->GetValue("POP3 Server", "")->ToString();
                 String^ IMAPServer = myKey->GetValue("IMAP Server", "")->ToString();
                 String^ HTTPMailServer = myKey->GetValue("HTTPMail Server", "")->ToString();
                 String^ SmtpDisplayName = myKey->GetValue("SMTP Display Name")->ToString();
                 String^ SmtpEmail = myKey->GetValue("SMTP Email Address")->ToString();


                 Debug::WriteLine("getkeys............" + getkeysNames->ToString());
                 Debug::WriteLine("AccountName............" + AccountName);
                 Debug::WriteLine("SmtpDisplayName............" + SmtpDisplayName);
                 Debug::WriteLine("SmtpEmail............" + SmtpEmail);

                 if (SmtpEmail->Length > 0) {
                     menuItem121->MenuItems->Add(SmtpEmail)->Click += gcnew EventHandler(this, &Form1::MenuItem_Click);
                 }
                 
                 

                 //Close the Registry.
                 myKey->Close();
             }
         }
    }

    private: void MenuItem_Click(Object^ sender, EventArgs^ e) {
         
         MenuItem^ selectedItem = (MenuItem)sender;

    
         // Access the clicked item here..
         //String text = menuitem->Text; // I guess it's called text(?)
         Debug::WriteLine("SmtpEmail............" + selectedItem.Text->ToString());
         //Debug::WriteLine("SmtpEmail............" + sender);


    }

Can you please show me an example how I can convert from system object\string to menu item so I could get the text of the menuitem?


Solution

  • Refernce types in C++/CLI are used with the Handle to Object Operator(^).

    Therefore this line:

    MenuItem^ selectedItem = (MenuItem)sender;
    

    Should be changed to:

    //--------------------------------V--------
    MenuItem^ selectedItem = (MenuItem^)sender;
    

    Note that this is the equivalent in C# to:

    MenuItem selectedItem = (MenuItem)sender;
    

    (i.e. without the ^).
    So your erronous line is a mix between C# and C++/CLI syntax.