2011-03-18 61 views
2

正如你可能从这篇文章的标题中收集的,我即将破解。WPF,WinForms,ActiveX控件以及我的消失灵敏度(调用DragMove()以响应WinForms控件的MouseDown事件)

好吧,所以它是这样的:我有一个WPF窗口托管一个WinForms窗体,该窗体依次托管一个ActiveX控件。这完全归功于传统组件,并希望为透明WPF窗口的不透明度设置动画。你不能仅仅感觉到乐趣吗?!

...所以,我想能够拖动我的透明WPF窗口,通过在窗口的各个区域向下鼠标调用DragMove。这很好,我可以忍受当前的行为,但如果我也可以通过我的WinForms组件生成的MouseDown事件拖动窗口,那将会很好。于是,我带着明显的方法:

void Init() 
{ 
    MyWinForm form = new MyWinForm(); 
    form.SomeControl.MouseDown = form_MouseDown; 
} 

void form_MouseDown(object sender, MouseEventArgs e) 
{ 
    if(e.Button == MouseButtons.Left) 
    { 
     DragMove(); 
    } 
} 

然而,我的应用程序崩溃,并显示以下信息:

只能调用DragMove当鼠标主按键时。

是啊,没错,但左(主)按钮按下按钮(我知道这可能是左手鼠标有问题,但让我们避免现在)。因此,对于System.Windows.Forms.Control,由WPF控件生成的鼠标事件的简单代码再次失败。有人对此有经验吗?预先感谢您提供的任何建议。

TLDR;从System.Windows.Controls.MouseDown事件中调用DragMove()会使应用程序崩溃。我接受任何解决方法。

回答

2

考虑使用反射DragMove()代码,我来此解决方案:我们可以写或拥有DragMove(IntPtr hWnd),不执行按钮状态检查,但我们必须明确MouseDown事件处理程序释放鼠标捕获。

public static class Utility 
{ 
    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr h, int msg, IntPtr lp, IntPtr wp); 

    public static void DragMove(IntPtr hwnd) 
    { 
     const int WM_SYSCOMMAND = 0x112; 
     const int WM_LBUTTONUP = 0x202; 

     SendMessage(hwnd, WM_SYSCOMMAND, (IntPtr)0xf012, IntPtr.Zero); 
     SendMessage(hwnd, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero); 
    } 
} 

,改变你的MouseDown处理程序只是有点:

void form_MouseDown(object sender, MouseEventArgs e) 
{ 
    if(e.Button == MouseButtons.Left) 
    { 
     // it is necessary to release mouse capture, so that 
     // WPF window will be able to capture mouse input 
     ((Control)sender).Capture = false; 
     // use helper to acquire window handle 
     var helper = new System.Windows.Interop.WindowInteropHelper(
      your_window_reference_goes_here); 
     Utility.DragMove(helper.Handle); 
    } 
} 

我没有ActiveX控件测试,但它与简单的WinForms控制工作,在WindowsFormsControlHost托管至少在Win7旗舰版64位。

+0

为什么我似乎总是忘记反射器?无论如何,你先生一直非常有帮助。非常感谢,它运作良好,并教会我一些新的东西。干杯。 – 2011-03-18 16:55:04