WPF窗口和WndProc

时间:2014-04-17 19:14:39

标签: wpf window wndproc

下面的代码片段取自“WPF 4 Unleashed”。它演示了Windows 7中的hwo,可以使用WIN32 API创建Aero Glass效果。在此演示中,WndProc事件过程用于Window实例。我注意到在此例程中没有调用默认窗口过程,就好像没有其他事件需要由该WPF窗口处理。

是什么让我发布这个问题 - 这更多是关于WPF的一般问题 - 是WPF窗口通常处理的事件(我确信它们中有很多)是否由其他人处理程序。换句话说,WPF窗口是否与WinForms不同---是否通过其他方式从操作系统(鼠标单击,鼠标移动)获取消息?

 [StructLayout(LayoutKind.Sequential)]
    public struct MARGINS
    {
        public MARGINS(Thickness t)
        {
            Left = (int)t.Left;
            Right = (int)t.Right;
            Top = (int)t.Top;
            Bottom = (int)t.Bottom;
        }
        public int Left;
        public int Right;
        public int Top;
        public int Bottom;
    }

    public class GlassHelper
    {
            [DllImport("dwmapi.dll", PreserveSig=false)]
            static extern void DwmExtendFrameIntoClientArea( IntPtr hWnd, ref MARGINS pMarInset);
            [DllImport("dwmapi.dll", PreserveSig=false)]
            static extern bool DwmIsCompositionEnabled();

            public static bool ExtendGlassFrame(Window window, Thickness margin)
            {
                   if (!DwmIsCompositionEnabled())
                        return false;
                   IntPtr hwnd = new WindowInteropHelper(window).Handle;
                   if (hwnd == IntPtr.Zero)
                       throw new InvalidOperationException(
                   "The Window must be shown before extending glass.");
                    // Set the background to transparent from both the WPF and Win32 perspectives
                   window.Background = Brushes.Transparent;
                   HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor =Colors.Transparent;
                   MARGINS margins = new MARGINS(margin);
                   DwmExtendFrameIntoClientArea(hwnd, ref margins);
                   return true;
            }
    }

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        // This can’t be done any earlier than the SourceInitialized event:
        GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
        // Attach a window procedure in order to detect later enabling of desktop
        // composition
        IntPtr hwnd = new WindowInteropHelper(this).Handle;
        HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_DWMCOMPOSITIONCHANGED)
        {
            // Reenable glass:
            GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
            handled = true;
        }
        return IntPtr.Zero;
    }

    private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

2 个答案:

答案 0 :(得分:0)

在使用WndProc方面,WPF窗口与WinForms窗口相同。将代码段放入我的WPF应用程序中没有问题。事实上,我没有找到任何WndProc相关的代码,到目前为止在WPF中没有用。

答案 1 :(得分:0)

WPF窗口就像Windows窗体一样,与经典Windows窗口一样,它们所有都有Message Loop用于接收消息和WindowProc(实际名称可以是任何程序员选择让它来处理它们。所有窗口都可以是子类(如About Window Procedures中所示),至少在WPF以下的级别。我不知道Windows窗体或WPF的WndProc是否将相关窗口子类化,但它们可能是。