Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How can I get the MouseDown event to be called when clicking on the HwndHost window?

I have tried the following:

In C++/CLI:
C++
public ref class GameWindow : public HwndHost
{
    // source
};


In C#:
C#
public partial class MainWindow : Window
{
    // Only important source displayed...

    private GameWindow mWindowWorld;

    private void Window_Loaded( Object sender, RoutedEventArgs e )
    {
        mWindowWorld = new GameWindow();

        // Tried this first...
        mWindowWorld.MouseDown += new MouseButtonEventHandler( Window_World_MouseDown );

        // Still does not work...
        mWindowWorld.AddHandler( FrameworkElement.MouseDownEvent, new MouseButtonEventHandler( Window_World_MouseDown ), true );

        Window_World.Child = mWindowWorld;
    }

    private void Window_World_MouseDown( Object sender, MouseButtonEventArgs e )
    {
        base.OnMouseDown( e ); // breakpoint set here

        if( e.MiddleButton == MouseButtonState.Pressed )
        {}

        if( e.RightButton == MouseButtonState.Pressed )
        {}
    }
};


In XAML:
XML
<!-- Tried this as well... -->
<Border Name="Window_World" MouseDown="Window_World_MouseDown" BorderThickness="2" BorderBrush="#666666" Margin="0,0,8,0" />


I have also tried using the PreviewMouseDown types, but that also did not work.

If getting the MouseEvent to work this way is not possible, then what is the reason for this?
Posted
Comments
Sergey Alexandrovich Kryukov 25-Aug-13 21:52pm    
First of all, why using this class at all? This is only used for interop...
—SA
jmclaine 25-Aug-13 22:01pm    
I have rendering code for DirectX written in C++, and did not want to rewrite it in C#.
Sergey Alexandrovich Kryukov 25-Aug-13 22:48pm    
I see...
—SA

1 solution

The events for the mouse can be called through C# via the interop using a delegate.

In C++/CLI:
C++
public ref class GameWindow : public HwndHost
{
    delegate void func0();

    func0^        OnLeftMouseDown;
    func0^        OnRightMouseDown;
    func0^        OnMiddleMouseDown;
    func0^        OnMouseMove;

    IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled )
    {
        switch( msg )
        {
            case WM_IME_SETCONTEXT:
                if( LOWORD( wParam.ToInt32() ) > 0)
                    SetFocus( mHWND );

                handled = true;
                return IntPtr::Zero;

            case WM_LBUTTONDOWN:
                OnLeftMouseDown();

                handled = true;
                return IntPtr::Zero;

            case WM_RBUTTONDOWN:
                OnRightMouseDown();

                handled = true;
                return IntPtr::Zero;

            case WM_MBUTTONDOWN:
                OnMiddleMouseDown();

                handled = true;
                return IntPtr::Zero;

            case WM_MOUSEMOVE:
                OnMouseMove();

                handled = true;
                return IntPtr::Zero;
        }

        handled = false;
        return IntPtr::Zero;
    }
};


In C#:
C#
public partial class MainWindow : Window
{
    // Only important source displayed...

    private GameWindow mWindowWorld;
    private Point      mMousePos;
 
    private void Window_Loaded( Object sender, RoutedEventArgs e )
    {
        mWindowWorld = new GameWindow();
 
        mWindowWorld.OnLeftMouseDown   = Window_World_OnLeftMouseDown;
        mWindowWorld.OnRightMouseDown  = Window_World_OnRightMouseDown;
        mWindowWorld.OnMiddleMouseDown = Window_World_OnMiddleMouseDown;
        mWindowWorld.OnMouseMove       = Window_World_OnMouseMove;
 
        Window_World.Child = mWindowWorld;
    }
 
    private void Window_World_OnLeftMouseDown()
    {
        // TODO: Perform desired actions here.
    }

    private void Window_World_OnRightMouseDown()
    {
        // TODO: Perform desired actions here.
    }

    private void Window_World_OnMiddleMouseDown()
    {
        // TODO: Perform desired actions here.
    }

    private void Window_World_OnMouseMove()
    {
        // Probably want to do something like this...
        Point mousePos = Mouse.GetPosition( mWindowWorld );
        mMousePos = new Point( mousePos.X, mousePos.Y );
    }
};


Although creating delegates is one solution, I ultimately ended up creating each mouse button function in the GameWindow class for code cleanliness. I then derived from that class, so I could keep the HwndHost separated from the main app.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900