今天写程序的时候遇到过奇怪的现象
代码如下: public partial class Form1 : Form
{
private Brush backBrush;
public Form1()
{
DoubleBuffered = true;
InitializeComponent(); backBrush = new SolidBrush(BackColor);
TransparencyKey = BackColor;
}
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.FillRectangle(backBrush, ClientRectangle);
}
}按常规思路来想,Form1在显示时,会是一个中间透明的窗体,当你右击此透明区域时,它会显示此窗体后面的东西的右击响应!
但事实上,当你在上面窗体的透明区域右击时,没有任何反应!
也就是说,此窗体看起来像是假透明!
当然,如果把DoubleBufferd设为false,或者不重写OnPaintBackground方法,它便正常了——真透明!
为什么会出现这种现象呢?
如果我又想将DoubleBufferd设为true,又像上面重写OnPaintBackground方法,还要得到真透明,该如何办?
望各位朋友指点一二,不胜感激!
代码如下: public partial class Form1 : Form
{
private Brush backBrush;
public Form1()
{
DoubleBuffered = true;
InitializeComponent(); backBrush = new SolidBrush(BackColor);
TransparencyKey = BackColor;
}
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.FillRectangle(backBrush, ClientRectangle);
}
}按常规思路来想,Form1在显示时,会是一个中间透明的窗体,当你右击此透明区域时,它会显示此窗体后面的东西的右击响应!
但事实上,当你在上面窗体的透明区域右击时,没有任何反应!
也就是说,此窗体看起来像是假透明!
当然,如果把DoubleBufferd设为false,或者不重写OnPaintBackground方法,它便正常了——真透明!
为什么会出现这种现象呢?
如果我又想将DoubleBufferd设为true,又像上面重写OnPaintBackground方法,还要得到真透明,该如何办?
望各位朋友指点一二,不胜感激!
首先 我们先把你要制作的窗体的 FormBorderStyle属性 设为FormBorderStyle.None。引用名字空间 using System.Runtime.InteropServices;然后在窗体类中写入一下代码private const uint WS_EX_LAYERED = 0x80000;
private const int WS_EX_TRANSPARENT = 0x20;
private const int GWL_STYLE = (-16);
private const int GWL_EXSTYLE = (-20);
private const int LWA_ALPHA = 0x2; [DllImport("user32", EntryPoint = "SetWindowLong")]
private static extern uint SetWindowLong(
IntPtr hwnd,
int nIndex,
uint dwNewLong
); [DllImport("user32", EntryPoint = "GetWindowLong")]
private static extern uint GetWindowLong(
IntPtr hwnd,
int nIndex
); [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
private static extern int SetLayeredWindowAttributes(
IntPtr hwnd,
int crKey,
int bAlpha,
int dwFlags
);在增加一个方法
/// <summary>
/// 使窗口有鼠标穿透功能
/// </summary>
public void CanPenetrate()
{
uint intExTemp = GetWindowLong(this.Handle, GWL_EXSTYLE);
uint oldGWLEx = SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
SetLayeredWindowAttributes(this.Handle, 0, 100, LWA_ALPHA);
} 如果你想让你的窗体实现可以穿透,就调用这个方法。
最后让窗体去掉穿透功能的话,只要执行下面的代码就可以了。
this.FormBorderStyle = FormBorderStyle.None;
使用其他方式
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll")]
public extern static IntPtr GetDesktopWindow(); [DllImport("user32.dll")]
public extern static bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
public static uint LWA_COLORKEY = 0x00000001;
public static uint LWA_ALPHA = 0x00000002; [DllImport("user32.dll")]
public extern static uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
public extern static uint GetWindowLong(IntPtr hwnd, int nIndex); public enum WindowStyle : int
{
GWL_EXSTYLE = -20
} public enum ExWindowStyle : uint
{
WS_EX_LAYERED = 0x00080000
} protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams; cp.Parent = DesktopWinAPI.GetDesktopWindow();
cp.ExStyle = 0x00000080 | 0x00000008;//WS_EX_TOOLWINDOW | WS_EX_TOPMOST return cp;
}
} private void SetWindowTransparent(byte bAlpha)
{
try
{
SetWindowLong(this.Handle, (int)DesktopWinAPI.WindowStyle.GWL_EXSTYLE,
GetWindowLong(this.Handle, (int)DesktopWinAPI.WindowStyle.GWL_EXSTYLE) | (uint)DesktopWinAPI.ExWindowStyle.WS_EX_LAYERED);
SetLayeredWindowAttributes(this.Handle, 0, bAlpha, DesktopWinAPI.LWA_COLORKEY | DesktopWinAPI.LWA_ALPHA);
}
catch
{
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.SetWindowTransparent(100);
}