locked
Handling event in native c++ class

    Question

  • I would like to handle a button clicked event in a native c++ class.  I have tried creating a 'handler' object derived from 'Object' to handle the event and then calling a c++ method.  For example I tired the following code:

    ref class GButtonHandler sealed : public Object
    {
    public:
        void Button_Click(Object^ sender, RoutedEventArgs^ e)
        {
        }

        GTextBlockHandler(GButtonImpl * pButtonImpl, Button ^ button)
        {
            button->Click += ref new RoutedEventHandler(this, &GTextBlockHandler::Button_Click);
        }
    };

    Thinking that I could squirrel away the pButtonImpl pointer and then use it to call a native function in the 'Button_Clicked' function.  However on compiling this code, I get the error:

    error C3986: '{ctor}': signature of public member contains native type 'GButtonImpl'

    So it seems that it does not like me passing in native classes into an ref object.  Is there a way to do this?

    Note that I am completely new to developing Metro style apps, so bear with me!

    Thanks.

    Saturday, June 30, 2012 3:49 PM

Answers

  • Ok, it all makes sense to me now.  For anyone else who is interested, the reason you cannot have WinRT Objects with public functions that have native C++ arguments is that these objects would then not be consumable by non C++ code.  However, the (obvious?) solution is to make the constructor private and have the class that creates the Object declared as a 'friend' class (duh!).  Then all is well, the compiler is happy, and I am happy.

    Thanks to all who took the time to read this.


    • Edited by John Gaby Sunday, July 01, 2012 9:44 PM
    • Marked as answer by Jesse Jiang Monday, July 02, 2012 8:48 AM
    Sunday, July 01, 2012 9:37 PM

All replies

  • Ok, it all makes sense to me now.  For anyone else who is interested, the reason you cannot have WinRT Objects with public functions that have native C++ arguments is that these objects would then not be consumable by non C++ code.  However, the (obvious?) solution is to make the constructor private and have the class that creates the Object declared as a 'friend' class (duh!).  Then all is well, the compiler is happy, and I am happy.

    Thanks to all who took the time to read this.


    • Edited by John Gaby Sunday, July 01, 2012 9:44 PM
    • Marked as answer by Jesse Jiang Monday, July 02, 2012 8:48 AM
    Sunday, July 01, 2012 9:37 PM
  • Thanks for sharing the solution.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Monday, July 02, 2012 8:48 AM
  • Alternatively, an elegant solution is to declare your constructor internal (like in C#). So it can be used from within your assembly. 

    ref class GButtonHandler sealed : public Object
    {
    public:
        void Button_Click(Object^ sender, RoutedEventArgs^ e);
    internal:
        // internal methods can use native types
        GTextBlockHandler(GButtonImpl * pButtonImpl, Button ^ button);
    };

    Wednesday, July 11, 2012 12:05 AM
  • I have never seen the 'internal' tag before.  I will have to give that a look see.  Thanks for the tip.
    Thursday, July 12, 2012 7:40 PM