WPF中不規則窗體與WindowsFormsHost控制元件的相容問題完美解決方案

weixin_33912246發表於2018-07-12
原文:WPF中不規則窗體與WindowsFormsHost控制元件的相容問題完美解決方案

         首先先得瑟一下,有關WPF中不規則窗體與WindowsFormsHost控制元件不相容的問題,網上給出的解決方案不能滿足所有的情況,是有特定條件的,比如  WPF中不規則窗體與WebBrowser控制元件的相容問題解決辦法該網友的解決辦法也是別出心裁的,為什麼這樣說呢,你下載了他的程式認真讀一下就便知道,他的webBrowser控制元件的是單獨放在一個Form中,讓這個Form與WPF中的一個Bord控制元件進行關聯,進行同步移動,但是在移動的時候會出現閃爍,並且還會出現運動的白點,使用者體驗肯定不好。
      OK,繞了一大圈,還是言歸正傳吧,為什麼會出現該問題呢,是什麼原因導致在WPF中設定了透明窗體之後,嵌入WinForm中的控制元件會顯示不了呢。一開始我以為是沒有正常載入,還要我有UISPY,通過這個軟體,我捕獲了一下當前執行的程式,發現我在WPF中內嵌的WinForm控制元件已經載入上了,只是沒有看到而已罷了。很鬱悶啊。
     悲催的程式,頭疼啊,是什麼原因導致的呢,網上查資料,找到了http://msdn.microsoft.com/zh-cn/library/aa970688.aspx ,讓我瞭解了不少知識。由於專案要用到透明窗體還要製作圓角窗體,說以本來打算不改變WPF中對window的設定,即不改變WindowStyle=“None” 和AllowTransparent = “True”這些設定,想在在WindowsFormsHost上做一些設定,發現這條路走不通。浪費了不少時間。
     此路不通只有換思路了,那麼把AllowTransparent =“false” ,然後就可以顯示,呵呵……當然還要修改啊,WPF的窗體多難看啊,外邊有一個邊框。怎麼搞去啊,怎樣辦,這也是一個問題啊。想用WPF的特性,悲劇了,好像沒有相關的方法啊。
      OK,路還是有的,程式設計師就是來解決辦法的,怎麼辦,只能呼叫Windows的API,把最外層的那層邊框被去掉了。那麼需要什麼呢,思路是有了,對吧,那麼就行動吧,google 和百度一通,發現還真有不少例子,c++的例子最全面,可以參考一下。那麼就整理了一下需要這些函式:
     SetWindowLong   設定值window的樣式
     GetWindowLong   獲取window的樣式
     SetWindowRgn     設定window的工作區
     CreateRoundRectRgn  建立帶有圓角的區域
     SetLayeredWindowAttributes  設定層次窗體,進行透明度的設定
直接百度,百科有對他們的詳細解釋,不過給出的是C++的解釋,那麼需要你對C++的東西進行轉化成C#的東西,有關C#如何呼叫C++的DLL檔案,百度和google中有你想要的答案,我就補多少了,不過要注意型別的轉化和字元
集的轉化。
下面我把我轉化好的函式給大家貼上來,以饗讀者。

    public class NativeMethods
    {
        /// <summary>
        /// 帶有外邊框和標題的windows的樣式
        /// </summary>
        public const long WS_CAPTION = 0X00C0000L;

        // public const long WS_BORDER = 0X0080000L;

        /// <summary>
        /// window 擴充套件樣式 分層顯示
        /// </summary>
        public const long WS_EX_LAYERED = 0x00080000L;

        /// <summary>
        /// 帶有alpha的樣式
        /// </summary>
        public const long LWA_ALPHA = 0x00000002L;

        /// <summary>
        /// 顏色設定
        /// </summary>
        public const long LWA_COLORKEY = 0x00000001L;

        /// <summary>
        /// window的基本樣式
        /// </summary>
        public const int GWL_STYLE = -16;

        /// <summary>
        /// window的擴充套件樣式
        /// </summary>
        public const int GWL_EXSTYLE = -20;

        /// <summary>
        /// 設定窗體的樣式
        /// </summary>
        /// <param name="handle">操作窗體的控制程式碼</param>
        /// <param name="oldStyle">進行設定窗體的樣式型別.</param>
        /// <param name="newStyle">新樣式</param>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern void SetWindowLong(IntPtr handle, int oldStyle, long newStyle);

        /// <summary>
        /// 獲取窗體指定的樣式.
        /// </summary>
        /// <param name="handle">操作窗體的控制程式碼</param>
        /// <param name="style">要進行返回的樣式</param>
        /// <returns>當前window的樣式</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern long GetWindowLong(IntPtr handle, int style);

        /// <summary>
        /// 設定窗體的工作區域.
        /// </summary>
        /// <param name="handle">操作窗體的控制程式碼.</param>
        /// <param name="handleRegion">操作窗體區域的控制程式碼.</param>
        /// <param name="regraw">if set to <c>true</c> [regraw].</param>
        /// <returns>返回值</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern int SetWindowRgn(IntPtr handle, IntPtr handleRegion, bool regraw);

        /// <summary>
        /// 建立帶有圓角的區域.
        /// </summary>
        /// <param name="x1">左上角座標的X值.</param>
        /// <param name="y1">左上角座標的Y值.</param>
        /// <param name="x2">右下角座標的X值.</param>
        /// <param name="y2">右下角座標的Y值.</param>
        /// <param name="width">圓角橢圓的 width.</param>
        /// <param name="height">圓角橢圓的 height.</param>
        /// <returns>hRgn的控制程式碼</returns>
        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int width, int height);

        /// <summary>
        /// Sets the layered window attributes.
        /// </summary>
        /// <param name="handle">要進行操作的視窗控制程式碼</param>
        /// <param name="colorKey">RGB的值</param>
        /// <param name="alpha">Alpha的值,透明度</param>
        /// <param name="flags">附帶引數</param>
        /// <returns>true or false</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern bool SetLayeredWindowAttributes(IntPtr handle, ulong colorKey, byte alpha, long flags);
    }
      下面的問題就是如何進行操作了,首先在進行嵌入WinForm控制元件的WPF窗體中新增一個Load事件,在事件中新增如下程式碼:
           // 獲取窗體控制程式碼
            IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;

            // 獲得窗體的 樣式
            long oldstyle = NativeMethods.GetWindowLong(hwnd, NativeMethods.GWL_STYLE);

            // 更改窗體的樣式為無邊框窗體
            NativeMethods.SetWindowLong(hwnd, NativeMethods.GWL_STYLE, oldstyle & ~NativeMethods.WS_CAPTION);

            // SetWindowLong(hwnd, GWL_EXSTYLE, oldstyle & ~WS_EX_LAYERED);
            // 1 | 2 << 8 | 3 << 16  r=1,g=2,b=3 詳見winuse.h檔案
            // 設定窗體為透明窗體
            NativeMethods.SetLayeredWindowAttributes(hwnd, 1 | 2 << 8 | 3 << 16, 0, NativeMethods.LWA_ALPHA);

            // 建立圓角窗體  12 這個值可以根據自身專案進行設定
            NativeMethods.SetWindowRgn(hwnd, NativeMethods.CreateRoundRectRgn(0, 0, Convert.ToInt32(this.ActualWidth), Convert.ToInt32(this.ActualHeight), 12, 12), true);

  還有就是窗體大小改變之後還要重畫圓角窗體,否則出現很不理想的顯示效果,新增如下事件程式碼,解決窗體大小改變的時候,重畫窗體的圓角區域:
        /// <summary>
        /// Handles the SizeChanged event of the DesktopShell control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
        private void DesktopShell_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            // 獲取窗體控制程式碼
            IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;

            // 建立圓角窗體
            NativeMethods.SetWindowRgn(hwnd,NativeMethods.CreateRoundRectRgn(0, 0, Convert.ToInt32(this.ActualWidth), Convert.ToInt32(this.ActualHeight), 12, 12), true);
        }

   

PS:有網友在操作的過程中,發現工作列中不顯示右擊的系統選單的問題。

其實這個問題我也遇到過,不過已經修復了該問題。下面貼上如何修復該問題的程式碼。具體原因,最後分析。

在NativieMethods類中新增如下程式碼:

        /// <summary>
        /// 系統選單
        /// </summary>
        public const long WS_SYSMENU = 0x00080000L;
另外我新建了一個類進行進行改變窗體的大家,改類名為:ChangeWindowSize,

該類程式碼為:

    /// <summary>
    /// 拖動窗體四角,可以改變窗體的大小
    /// </summary>
    public class ChangeWindowSize
    {
        /// <summary>
        /// 邊框寬度
        /// </summary>
        private readonly int Thickness = 4;

        /// <summary>
        /// 改變大小的通知訊息
        /// </summary>
        private const int WMNCHITTEST = 0x0084;

        /// <summary>
        /// 拐角寬度
        /// </summary>
        private readonly int angelWidth = 12;

        /// <summary>
        /// 要改變窗體大小的物件
        /// </summary>
        private Window window = null;

        /// <summary>
        /// 滑鼠座標
        /// </summary>
        private Point mousePoint = new Point();

        /// <summary>
        /// 建構函式,初始化目標窗體物件
        /// </summary>
        /// <param name="window">目標窗體</param>
        public ChangeWindowSize(Window window)
        {
            this.window = window;
        }

        /// <summary>
        /// 進行註冊鉤子
        /// </summary>
        public void RegisterHook()
        {
            HwndSource hwndSource = PresentationSource.FromVisual(this.window) as HwndSource;
            if (hwndSource != null)
            {
                hwndSource.AddHook(new HwndSourceHook(this.WndProc));
            }
        }

        /// <summary>
        /// 窗體回撥程式
        /// </summary>
        /// <param name="hwnd">窗體控制程式碼</param>
        /// <param name="msg">訊息</param>
        /// <param name="wideParam">附加引數1</param>
        /// <param name="longParam">附加引數2</param>
        /// <param name="handled">是否處理</param>
        /// <returns>返回控制程式碼</returns>
        public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wideParam, IntPtr longParam, ref bool handled)
        {
            switch (msg)
            {
                case WMNCHITTEST:
                    this.mousePoint.X = longParam.ToInt32() & 0xFFFF;
                    this.mousePoint.Y = longParam.ToInt32() >> 16;

                    // 視窗位置  // 視窗左上角
                    if (this.mousePoint.Y - this.window.Top <= this.angelWidth
                       && this.mousePoint.X - this.window.Left <= this.angelWidth)
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOPLEFT);
                    }
                    else if (this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.angelWidth
                       && this.mousePoint.X - this.window.Left <= this.angelWidth) // 視窗左下角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOMLEFT);
                    }
                    else if (this.mousePoint.Y - this.window.Top <= this.angelWidth
                       && this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.angelWidth) // 視窗右上角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOPRIGHT);
                    }
                    else if (this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.angelWidth
                       && this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.angelWidth) // 視窗右下角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOMRIGHT);
                    }
                    else if (this.mousePoint.X - this.window.Left <= this.Thickness) // 視窗左側
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTLEFT);
                    }
                    else if (this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.Thickness) // 視窗右側
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTRIGHT);
                    }
                    else if (this.mousePoint.Y - this.window.Top <= this.Thickness) // 視窗上方
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOP);
                    }
                    else if (this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.Thickness) // 視窗下方
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOM);
                    }
                    else // 視窗移動
                    {
                        // handled = true;
                        return new IntPtr((int)HitTest.HTCAPTION);
                    }
            }

            return IntPtr.Zero;
        }
    }
修改ChangeWindowSize類,

新增成員變數:

        /// <summary>
        /// 視窗的大小和位置將要被改變時的訊息
        /// </summary>
        private const int WMWINDOWPOSCHANGING = 0x0046;

修改回撥函式:
        /// <summary>
        /// 窗體回撥程式
        /// </summary>
        /// <param name="hwnd">窗體控制程式碼</param>
        /// <param name="msg">訊息</param>
        /// <param name="wideParam">附加引數1</param>
        /// <param name="longParam">附加引數2</param>
        /// <param name="handled">是否處理</param>
        /// <returns>返回控制程式碼</returns>
        public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wideParam, IntPtr longParam, ref bool handled)
        {
            // 獲得窗體的 樣式
            long oldstyle = MedSys.PresentationCore.AdjustWindow.NativeMethods.GetWindowLong(hwnd, MedSys.PresentationCore.AdjustWindow.NativeMethods.GWL_STYLE);
            switch (msg)
            {
                case WMNCHITTEST:
                    this.mousePoint.X = longParam.ToInt32() & 0xFFFF;
                    this.mousePoint.Y = longParam.ToInt32() >> 16;

                    // 更改窗體的樣式為無邊框窗體
                    MedSys.PresentationCore.AdjustWindow.NativeMethods.SetWindowLong(hwnd, MedSys.PresentationCore.AdjustWindow.NativeMethods.GWL_STYLE, oldstyle & ~MedSys.PresentationCore.AdjustWindow.NativeMethods.WS_CAPTION);

                    // 視窗位置  // 視窗左上角
                    if (this.mousePoint.Y - this.window.Top <= this.angelWidth
                       && this.mousePoint.X - this.window.Left <= this.angelWidth)
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOPLEFT);
                    }
                    else if (this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.angelWidth
                       && this.mousePoint.X - this.window.Left <= this.angelWidth) // 視窗左下角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOMLEFT);
                    }
                    else if (this.mousePoint.Y - this.window.Top <= this.angelWidth
                       && this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.angelWidth) // 視窗右上角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOPRIGHT);
                    }
                    else if (this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.angelWidth
                       && this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.angelWidth) // 視窗右下角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOMRIGHT);
                    }
                    else if (this.mousePoint.X - this.window.Left <= this.Thickness) // 視窗左側
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTLEFT);
                    }
                    else if (this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.Thickness) // 視窗右側
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTRIGHT);
                    }
                    else if (this.mousePoint.Y - this.window.Top <= this.Thickness) // 視窗上方
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOP);
                    }
                    else if (this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.Thickness) // 視窗下方
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOM);
                    }
                    else // 視窗移動
                    {
                        // handled = true;
                        // 更改窗體的樣式為無邊框窗體
                        return new IntPtr((int)HitTest.HTCAPTION);
                    }

                case WMWINDOWPOSCHANGING:

                    // 在將要改變的時候,是樣式新增系統選單
                    MedSys.PresentationCore.AdjustWindow.NativeMethods.SetWindowLong(hwnd, MedSys.PresentationCore.AdjustWindow.NativeMethods.GWL_STYLE, oldstyle & ~MedSys.PresentationCore.AdjustWindow.NativeMethods.WS_CAPTION | MedSys.PresentationCore.AdjustWindow.NativeMethods.WS_SYSMENU);
                    break;
            }

            return IntPtr.Zero;
        }
最後對主窗體過載如下函式:

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            ChangeWindowSize changeWindowSize = new ChangeWindowSize(this);
            changeWindowSize.RegisterHook();
        }
最大化最小化區域的修改,對主窗體新增如下事件:

        /// <summary>
        /// Resets the max size initialize.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void ResetMaxSizeInitialize(object sender, EventArgs e)
        {
            this.MaxWidth = SystemParameters.WorkArea.Width;
            this.MaxHeight = SystemParameters.WorkArea.Height;
        }
具體原因為:

    移動窗體的訊息和響應系統選單訊息之間產生衝突.

我上述解決的方案策略為:

   我採用迂迴策略,當開始進行移動的時候,去除系統選單的樣式,這樣就不能響應系統選單的訊息。移動完成時,新增系統選單的樣式,這樣再去點選工作列中系統的圖示便可以響應系統選單的訊息。


關於在Framework4.0無法工作的問題修復:

//-----------------------------------------------------------------------
// <copyright file="ChangeWindowSize.cs" company="Vadeware">
//     Copyright (c) Vadeware Enterprises. All rights reserved.
//     窗體
// </copyright>
//-----------------------------------------------------------------------
namespace MedSys.PresentationCore.AdjustWindow
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Interop;

    /// <summary>
    /// 拖動窗體四角,可以改變窗體的大小
    /// </summary>
    public class ChangeWindowSize
    {
        /// <summary>
        /// 邊框寬度
        /// </summary>
        private readonly int Thickness = 4;

        /// <summary>
        /// 改變大小的通知訊息
        /// </summary>
        private const int WMNCHITTEST = 0x0084;

        /// <summary>
        /// 視窗的大小和位置將要被改變時的訊息
        /// </summary>
        private const int WMWINDOWPOSCHANGING = 0x0046;

        /// <summary>
        /// 拐角寬度
        /// </summary>
        private readonly int angelWidth = 12;

        /// <summary>
        /// 要改變窗體大小的物件
        /// </summary>
        private Window window = null;

        /// <summary>
        /// 滑鼠座標
        /// </summary>
        private Point mousePoint = new Point();

        /// <summary>
        /// 建構函式,初始化目標窗體物件
        /// </summary>
        /// <param name="window">目標窗體</param>
        public ChangeWindowSize(Window window)
        {
            this.window = window;
        }

        /// <summary>
        /// 進行註冊鉤子
        /// </summary>
        public void RegisterHook()
        {
            HwndSource hwndSource = PresentationSource.FromVisual(this.window) as HwndSource;
            if (hwndSource != null)
            {
                hwndSource.AddHook(new HwndSourceHook(this.WndProc));
            }
        }

        /// <summary>
        /// 窗體回撥程式
        /// </summary>
        /// <param name="hwnd">窗體控制程式碼</param>
        /// <param name="msg">訊息</param>
        /// <param name="wideParam">附加引數1</param>
        /// <param name="longParam">附加引數2</param>
        /// <param name="handled">是否處理</param>
        /// <returns>返回控制程式碼</returns>
        public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wideParam, IntPtr longParam, ref bool handled)
        {
            // 獲得窗體的 樣式
            int oldstyle = MedSys.PresentationCore.AdjustWindow.NativeMethods.GetWindowLong(hwnd, MedSys.PresentationCore.AdjustWindow.NativeMethods.GWL_STYLE);
            switch (msg)
            {
                case WMNCHITTEST:
                    this.mousePoint.X = longParam.ToInt32() & 0xFFFF;
                    this.mousePoint.Y = longParam.ToInt32() >> 16;

                    // 更改窗體的樣式為無邊框窗體
                    MedSys.PresentationCore.AdjustWindow.NativeMethods.SetWindowLong(hwnd, MedSys.PresentationCore.AdjustWindow.NativeMethods.GWL_STYLE, oldstyle & ~MedSys.PresentationCore.AdjustWindow.NativeMethods.WS_CAPTION);

                    // 視窗位置  // 視窗左上角
                    if (this.mousePoint.Y - this.window.Top <= this.angelWidth
                       && this.mousePoint.X - this.window.Left <= this.angelWidth)
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOPLEFT);
                    }
                    else if (this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.angelWidth
                       && this.mousePoint.X - this.window.Left <= this.angelWidth) // 視窗左下角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOMLEFT);
                    }
                    else if (this.mousePoint.Y - this.window.Top <= this.angelWidth
                       && this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.angelWidth) // 視窗右上角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOPRIGHT);
                    }
                    else if (this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.angelWidth
                       && this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.angelWidth) // 視窗右下角
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOMRIGHT);
                    }
                    else if (this.mousePoint.X - this.window.Left <= this.Thickness) // 視窗左側
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTLEFT);
                    }
                    else if (this.window.ActualWidth + this.window.Left - this.mousePoint.X <= this.Thickness) // 視窗右側
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTRIGHT);
                    }
                    else if (this.mousePoint.Y - this.window.Top <= this.Thickness) // 視窗上方
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTTOP);
                    }
                    else if (this.window.ActualHeight + this.window.Top - this.mousePoint.Y <= this.Thickness) // 視窗下方
                    {
                        handled = true;
                        return new IntPtr((int)HitTest.HTBOTTOM);
                    }
                    else // 視窗移動
                    {
                        // handled = true;
                        // 更改窗體的樣式為無邊框窗體
                        return new IntPtr((int)HitTest.HTCAPTION);
                    }

                case WMWINDOWPOSCHANGING:

                    // 在將要改變的時候,是樣式新增系統選單
                    MedSys.PresentationCore.AdjustWindow.NativeMethods.SetWindowLong(hwnd, MedSys.PresentationCore.AdjustWindow.NativeMethods.GWL_STYLE, oldstyle & ~MedSys.PresentationCore.AdjustWindow.NativeMethods.WS_CAPTION | MedSys.PresentationCore.AdjustWindow.NativeMethods.WS_SYSMENU);
                    break;
            }

            return IntPtr.Zero;
        }
    }
}

//-----------------------------------------------------------------------
// <copyright file="NativeMethods.cs" company="Vadeware">
//     Copyright (c) Vadeware Enterprises. All rights reserved.
//    windows 函式的藉口介面函式
// </copyright>
namespace MedSys.PresentationCore.AdjustWindow
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// 主窗體內部類
    /// </summary>
    public class NativeMethods
    {
        /// <summary>
        /// 帶有外邊框和標題的windows的樣式
        /// </summary>
        public const int WS_CAPTION = 0X00C0000;

        /// <summary>
        /// 系統選單
        /// </summary>
        public const int WS_SYSMENU = 0x00080000;

        /// <summary>
        /// window 擴充套件樣式 分層顯示
        /// </summary>
        public const int WS_EX_LAYERED = 0x00080000;

        /// <summary>
        /// 帶有alpha的樣式
        /// </summary>
        public const int LWA_ALPHA = 0x00000002;

        /// <summary>
        /// 顏色設定
        /// </summary>
        public const int LWA_COLORKEY = 0x00000001;

        /// <summary>
        /// window的基本樣式
        /// </summary>
        public const int GWL_STYLE = -16;

        /// <summary>
        /// window的擴充套件樣式
        /// </summary>
        public const int GWL_EXSTYLE = -20;

        /// <summary>
        /// 設定窗體的樣式
        /// </summary>
        /// <param name="handle">操作窗體的控制程式碼</param>
        /// <param name="oldStyle">進行設定窗體的樣式型別.</param>
        /// <param name="newStyle">新樣式</param>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern void SetWindowLong(IntPtr handle, int oldStyle, int newStyle);

        /// <summary>
        /// 獲取窗體指定的樣式.
        /// </summary>
        /// <param name="handle">操作窗體的控制程式碼</param>
        /// <param name="style">要進行返回的樣式</param>
        /// <returns>當前window的樣式</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern int GetWindowLong(IntPtr handle, int style);

        /// <summary>
        /// 設定窗體的工作區域.
        /// </summary>
        /// <param name="handle">操作窗體的控制程式碼.</param>
        /// <param name="handleRegion">操作窗體區域的控制程式碼.</param>
        /// <param name="regraw">if set to <c>true</c> [regraw].</param>
        /// <returns>返回值</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern int SetWindowRgn(IntPtr handle, IntPtr handleRegion, bool regraw);

        /// <summary>
        /// 建立帶有圓角的區域.
        /// </summary>
        /// <param name="x1">左上角座標的X值.</param>
        /// <param name="y1">左上角座標的Y值.</param>
        /// <param name="x2">右下角座標的X值.</param>
        /// <param name="y2">右下角座標的Y值.</param>
        /// <param name="width">圓角橢圓的 width.</param>
        /// <param name="height">圓角橢圓的 height.</param>
        /// <returns>hRgn的控制程式碼</returns>
        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int width, int height);

        /// <summary>
        /// Sets the layered window attributes.
        /// </summary>
        /// <param name="handle">要進行操作的視窗控制程式碼</param>
        /// <param name="colorKey">RGB的值</param>
        /// <param name="alpha">Alpha的值,透明度</param>
        /// <param name="flags">附帶引數</param>
        /// <returns>true or false</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        public static extern bool SetLayeredWindowAttributes(IntPtr handle, uint colorKey, byte alpha, int flags);
    }
}


____2012年08月05日11點05分修改__新增Vs2008的Demo_____________________________________

應網友的要求,現將DMEO奉上。

該Demo為Framework3.5的,在Vs2008下執行沒有問題。

Demo下載連線:http://download.csdn.net/detail/wziyx513225244/4477441

感謝網友:huyunsuo 對我支援


____2012年09月21日17點36分修改__新增Vs2010的Demo_____________________________________

 應網友的要求,現將DMEO奉上。

該Demo為Framework4.0的,在Vs2010下執行沒有問題。

連結(收您1分,請您體諒和尊重原創):http://download.csdn.net/detail/wziyx513225244/4585821

感謝網友給出的解決方法和對此問題的關注。首先感謝mikejodden 給出的修改建議,以及 llhccyc 對該問題質疑。

同樣感謝其他人的關注。謝謝你們的關注。我將做的更好。

_________________________________                                                                                                              ___
 至此問題就全部解決了,如果有朋友有疑問,可以留言,能幫助到你,我很榮幸。

   請尊重作者的勞動果實,支援轉載,請註明部落格的出處。謝謝。

相關文章