窗体样式使用WS_EX_LAYERED后,无法绘制windows控件的解决办法
根据一副png图片绘制半透明窗体时,用了WS_EX_LAYERED后当前窗体再也不会处理paint事件,所以所含的子控件是一辈子也不会画出来的,但是这个控件确实存在,而且可以响应事件 。而此时windows画制窗体是使用UpdateLayeredWindow这个api函数的。
其实这个问题,3年前就在csdn网友miky的"笨笨钟"发布后就讨论过了,后来出了一个叫桌面天气秀 的东东也采用类似的技术。那时候我有幸拿到了miky的delphi下实现gdi+半透明窗体的一段代码,因为无法画出button等控件和 几位高人讨论过,这里是当时的讨论情况
http://borland.mblogger.cn/jinjazz/posts/21093.aspx
最终并没有很好的解决办法,而是通过大概如下的方法解决的
————————————————————————————————————
对于按钮,完全可以自己画两个图片然后盖在button上面,通过处理button的enter和leave消息来切换者两个图片来表达按钮状态
对于输入框..这个可以用一个让任何人看了都生气地办法,那就是....两个窗体 ,的确别人就是这么做的
可以用一个空心窗体只显示该显示的控件,然后盖在你的半透明窗体上面,并处理半透明窗体的move事件,让另外一个窗体同步移动或者做其它事情
效果如下:
以下是一些C#代码,Delphi的就不贴了
主Form的代码
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace WindowsApplication7
... {
public class Form1 : System.Windows.Forms.Form
... {
private System.ComponentModel.IContainer components;
public Form1()
... {
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
}
/**/ /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
... {
if ( disposing )
... {
if (components != null )
... {
components.Dispose();
}
}
base .Dispose( disposing );
}
Windows Form Designer generated code #region Windows Form Designer generated code
/**/ /// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
... {
this .button1 = new System.Windows.Forms.Button();
this .SuspendLayout();
//
// button1
//
this .button1.Cursor = System.Windows.Forms.Cursors.Hand;
this .button1.Location = new System.Drawing.Point( 20 , 20 );
this .button1.Name = " button1 " ;
this .button1.Size = new System.Drawing.Size( 113 , 51 );
this .button1.TabIndex = 1 ;
this .button1.Text = " button1 " ;
this .button1.MouseLeave += new System.EventHandler( this .button1_MouseLeave);
this .button1.Click += new System.EventHandler( this .button1_Click);
this .button1.MouseEnter += new System.EventHandler( this .button1_MouseEnter);
//
// Form1
//
this .AutoScaleBaseSize = new System.Drawing.Size( 6 , 14 );
this .ClientSize = new System.Drawing.Size( 184 , 123 );
this .Controls.Add( this .button1);
this .Name = " Form1 " ;
this .StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this .Text = " Form1 " ;
this .Load += new System.EventHandler( this .Form1_Load);
this .VisibleChanged += new System.EventHandler( this .Form1_VisibleChanged);
this .FormClosed += new System.Windows.Forms.FormClosedEventHandler( this .Form1_FormClosed);
this .MouseDown += new System.Windows.Forms.MouseEventHandler( this .Form1_MouseDown);
this .Move += new System.EventHandler( this .Form1_Move);
this .ResumeLayout( false );
}
#endregion
/**/ /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
... {
Application.Run( new Form1());
}
Form2 controlFrm = new Form2();
private void button1_Click( object sender, System.EventArgs e)
... {
MessageBox.Show(controlFrm,controlFrm.textBox1.Text);
}
protected override CreateParams CreateParams
... {
get
... {
CreateParams cp = base .CreateParams;
cp.ExStyle |= 0x00080000 ; // This form has to have the WS_EX_LAYERED extended style
return cp;
}
}
private void SetStyle1()
... {
Bitmap bm = Image.FromFile( @" Green.png " ) as Bitmap;
Bitmap bm2 = Image.FromFile( @" btn.png " ) as Bitmap;
Graphics g = Graphics.FromImage(bm);
g.DrawImage(bm2, 20 , 20 , new Rectangle( 0 , 0 , 90 , 50 ), GraphicsUnit.Pixel);
g.DrawString( " by jinjazz " , new Font( " Ariel " , 9 , FontStyle.Bold), new SolidBrush(Color.Black), new PointF( 40 , 50 ));
this .SetBitmap(bm, 255 );
}
private void SetStyle2()
... {
Bitmap bm = Image.FromFile( @" Green.png " ) as Bitmap;
Bitmap bm2 = Image.FromFile( @" btn.png " ) as Bitmap;
Graphics g = Graphics.FromImage(bm);
g.DrawImage(bm2, 15 , 15 , new Rectangle( 7 , 140 , 100 , 50 ), GraphicsUnit.Pixel);
g.DrawString( " by jinjazz " , new Font( " Ariel " , 9 , FontStyle.Bold), new SolidBrush(Color.Black), new PointF( 40 , 50 ));
this .SetBitmap(bm, 255 );
}
private void Form1_Load( object sender, System.EventArgs e)
... {
controlFrm.Show();
SetStyle1();
// this.TopMost = true;
controlFrm.TopMost = true ;
}
private void button1_MouseEnter( object sender, EventArgs e)
... {
SetStyle2();
}
private void button1_MouseLeave( object sender, EventArgs e)
... {
SetStyle1();
}
public void SetBitmap(Bitmap bitmap, byte opacity)
... {
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException( " The bitmap must be 32ppp with alpha-channel. " );
// The ideia of this is very simple,
// 1. Create a compatible DC with screen;
// 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
// 3. Call the UpdateLayeredWindow.
IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;
try
... {
hBitmap = bitmap.GetHbitmap(Color.FromArgb( 0 )); // grab a GDI handle from this GDI+ bitmap
oldBitmap = Win32.SelectObject(memDc, hBitmap);
Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
Win32.Point pointSource = new Win32.Point( 0 , 0 );
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0 ;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA;
Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0 , ref blend, Win32.ULW_ALPHA);
}
finally
... {
Win32.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
... {
Win32.SelectObject(memDc, oldBitmap);
// Windows.DeleteObject(hBitmap); // The documentation says that we have to use the Windows.DeleteObject... but since there is no such method I use the normal DeleteObject from Win32 GDI and it's working fine without any resource leak.
Win32.DeleteObject(hBitmap);
}
Win32.DeleteDC(memDc);
}
}
private System.Windows.Forms.Button button1;
private void Form1_MouseDown( object sender, System.Windows.Forms.MouseEventArgs e)
... {
Win32.ReleaseCapture();
Win32.SendMessage( this .Handle.ToInt32(), Win32.WM_SysCommand, Win32.SC_MOVE, 0 );
}
private void Form1_Move( object sender, EventArgs e)
... {
controlFrm.Location = this .Location;
}
private void Form1_VisibleChanged( object sender, EventArgs e)
... {
controlFrm.Visible = this .Visible;
}
private void Form1_FormClosed( object sender, FormClosedEventArgs e)
... {
controlFrm.Close();
}
}
}
显示子控件的Form代码
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication7
... {
public partial class Form2 : Form
... {
public Form2()
... {
InitializeComponent();
}
private System.ComponentModel.IContainer components = null ;
/**/ /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing"> 如果应释放托管资源,为 true;否则为 false。 </param>
protected override void Dispose( bool disposing)
... {
if (disposing && (components != null ))
... {
components.Dispose();
}
base .Dispose(disposing);
}
Windows 窗体设计器生成的代码 #region Windows 窗体设计器生成的代码
/**/ /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
... {
this .button1 = new System.Windows.Forms.Button();
this .textBox1 = new System.Windows.Forms.TextBox();
this .SuspendLayout();
//
// button1
//
this .button1.BackColor = System.Drawing.SystemColors.Control;
this .button1.Location = new System.Drawing.Point( 118 , 97 );
this .button1.Name = " button1 " ;
this .button1.Size = new System.Drawing.Size( 55 , 23 );
this .button1.TabIndex = 0 ;
this .button1.Text = " ok " ;
this .button1.UseVisualStyleBackColor = false ;
this .button1.Click += new System.EventHandler( this .button1_Click);
//
// textBox1
//
this .textBox1.Location = new System.Drawing.Point( 12 , 99 );
this .textBox1.Name = " textBox1 " ;
this .textBox1.Size = new System.Drawing.Size( 100 , 21 );
this .textBox1.TabIndex = 1 ;
this .textBox1.Text = " I Love Jinjazz " ;
//
// Form2
//
this .AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this .AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this .BackColor = System.Drawing.Color.LightPink;
this .ClientSize = new System.Drawing.Size( 184 , 123 );
this .Controls.Add( this .textBox1);
this .Controls.Add( this .button1);
this .FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this .Name = " Form2 " ;
this .ShowInTaskbar = false ;
this .StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this .Text = " Form2 " ;
this .TransparencyKey = System.Drawing.Color.LightPink;
this .ResumeLayout( false );
this .PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
internal System.Windows.Forms.TextBox textBox1;
private void button1_Click( object sender, EventArgs e)
... {
MessageBox.Show( this .textBox1.Text);
}
}
}
调用API的代码
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace WindowsApplication7
... {
class Win32
... {
public enum Bool
... {
False = 0 ,
True
} ;
[StructLayout(LayoutKind.Sequential)]
public struct Point
... {
public Int32 x;
public Int32 y;
public Point(Int32 x, Int32 y) ... { this .x = x; this .y = y; }
}
[StructLayout(LayoutKind.Sequential)]
public struct Size
... {
public Int32 cx;
public Int32 cy;
public Size(Int32 cx, Int32 cy) ... { this .cx = cx; this .cy = cy; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1 )]
struct ARGB
... {
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
[StructLayout(LayoutKind.Sequential, Pack = 1 )]
public struct BLENDFUNCTION
... {
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
public const Int32 ULW_COLORKEY = 0x00000001 ;
public const Int32 ULW_ALPHA = 0x00000002 ;
public const Int32 ULW_OPAQUE = 0x00000004 ;
public const byte AC_SRC_OVER = 0x00 ;
public const byte AC_SRC_ALPHA = 0x01 ;
[DllImport( " user32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
[DllImport( " user32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport( " user32.dll " , ExactSpelling = true )]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport( " gdi32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport( " gdi32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern Bool DeleteDC(IntPtr hdc);
[DllImport( " gdi32.dll " , ExactSpelling = true )]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport( " gdi32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern Bool DeleteObject(IntPtr hObject);
[DllImport( " user32.dll " , EntryPoint = " SendMessage " )]
public static extern int SendMessage( int hWnd, int wMsg, int wParam, int lParam);
[DllImport( " user32.dll " , EntryPoint = " ReleaseCapture " )]
public static extern int ReleaseCapture();
public const int WM_SysCommand = 0x0112 ;
public const int SC_MOVE = 0xF012 ;
public const int SC_MAXIMIZE = 61488 ;
public const int SC_MINIMIZE = 61472 ;
}
}
窗体样式使用WS_EX_LAYERED后,无法绘制windows控件的解决办法相关推荐
- win7 提示 由于无法验证发布者,windows阻止控件安装 解决办法
本文转载自: https://www.cnblogs.com/philzhou/archive/2011/01/26/1945153.html 作者:philzhou 转载请注明该声明. 对于一些企业 ...
- 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用
Dixon 原文 用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方 ...
- 关于 LDTP 操纵 windows 控件。
LDTP doc: https://ldtp.freedesktop.org/user-doc/ 对于 web 自动化,我们用 Selenium, 但是对于 windows 控件,我们可以使用 LDT ...
- Win7/8/10安装Centos7/Redhat7双系统丢失windows启动项的解决办法
Win7/8/10安装Centos7/Redhat7双系统后可能会丢失windows启动项,这是因为Linux系统默认将mbr改写成grub2,新安装的Linux系统默认不识别windows下的ntf ...
- Mac更新系统后,无法正常打开AE的解决办法
AE可以帮助您高效且精确地创建无数种引人注目的动态图形和震撼人心的视觉效果.利用与其他Adobe软件无与伦比的紧密集成和高度灵活的2D和3D合成,以及数百种预设的效果和动画,为您的电影.视频.DVD和 ...
- windows引导文件丢失解决办法
windows引导文件丢失解决办法 谁偷了我的启动文件?--Windows多重引导故障快速修复 现在安装多操作系统的朋友越来越多,但在多操作系统运行过程中偶尔出现的多重选单丢失.启动文件损坏.无法引导 ...
- 格式化 U盘/TF卡/SD卡 出错!!“windows无法完成格式化”解决办法。
插入U盘,双击显示磁盘未被格式化,想现在格式化吗?点了确定以后,又显示windows无法完成格式化.请问是怎么回事啊?还能修复吗? 在桌面回击我的电脑选择管理在弹出的计算机管理中选择磁盘管理然后选择U ...
- 换ssd后Oracle,更换SSD固态硬盘后电脑无法开机原因分析和解决办法
更换SSD固态硬盘后电脑无法开机原因分析和解决办法 有网友先自己电脑反应慢,将硬盘换成了SSD固态硬盘,自己使用Win8.1系统,重启电脑正常,但是系统更新后,电脑开机出现如下界面,提示: Windo ...
- 此计算机策略设置不允许安装win,系统管理员设置了系统策略,禁止进行此项安装”windows installer被禁用解决办法...
系统管理员设置了系统策略,禁止进行此项安装"windows installer被禁用解决办法 今天想为朋友做个手机归属地批量查询系统.在网吧想装一个ACCESS. 谁知出现下面这种情况. 看 ...
最新文章
- qt布局中listwidget 保持固定宽度_UI设计中响应式设计实用技巧
- 查找文件命令find总结以及查找大文件
- Canal解析数据报错:column size is not match for table xxxx 59 vs 57
- MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理
- Struts2学习笔记(五)之异常处理机制
- python中自带的模块_python中的模块详解
- windows下安装consul
- Java学习笔记2.2.1 常量与变量 - 变量
- linux 从一台服务器向另台服务器复制文件
- 新疆有没有教电脑编程C语言,新疆学习电脑编程,新疆学电脑编程哪里好,新疆学电脑编程效果怎么样...
- 多摩川读写EEPROM以及并口实现
- STL源码剖析——stl_algobase.h
- 全面的在线教育直播平台是怎样的呢?
- 定能解决No instances available for provider
- javaScript中什么时候用分号;
- android积分墙sdk,乐点 Android SDK 积分墙开发者文档
- 一文带你了解Serverless架构及应用场景
- 让每个生命带着尊严谢幕!淘宝竟有这样一家“临终关怀”网店
- Android系统 屏幕最低背光亮度值/最高背光亮度值 调试
- 双柱状图与双折线图混合