根据一副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;
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;
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;
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控件的解决办法相关推荐

  1. win7 提示 由于无法验证发布者,windows阻止控件安装 解决办法

    本文转载自: https://www.cnblogs.com/philzhou/archive/2011/01/26/1945153.html 作者:philzhou 转载请注明该声明. 对于一些企业 ...

  2. 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

    Dixon 原文  用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方 ...

  3. 关于 LDTP 操纵 windows 控件。

    LDTP doc: https://ldtp.freedesktop.org/user-doc/ 对于 web 自动化,我们用 Selenium, 但是对于 windows 控件,我们可以使用 LDT ...

  4. Win7/8/10安装Centos7/Redhat7双系统丢失windows启动项的解决办法

    Win7/8/10安装Centos7/Redhat7双系统后可能会丢失windows启动项,这是因为Linux系统默认将mbr改写成grub2,新安装的Linux系统默认不识别windows下的ntf ...

  5. Mac更新系统后,无法正常打开AE的解决办法

    AE可以帮助您高效且精确地创建无数种引人注目的动态图形和震撼人心的视觉效果.利用与其他Adobe软件无与伦比的紧密集成和高度灵活的2D和3D合成,以及数百种预设的效果和动画,为您的电影.视频.DVD和 ...

  6. windows引导文件丢失解决办法

    windows引导文件丢失解决办法 谁偷了我的启动文件?--Windows多重引导故障快速修复 现在安装多操作系统的朋友越来越多,但在多操作系统运行过程中偶尔出现的多重选单丢失.启动文件损坏.无法引导 ...

  7. 格式化 U盘/TF卡/SD卡 出错!!“windows无法完成格式化”解决办法。

    插入U盘,双击显示磁盘未被格式化,想现在格式化吗?点了确定以后,又显示windows无法完成格式化.请问是怎么回事啊?还能修复吗? 在桌面回击我的电脑选择管理在弹出的计算机管理中选择磁盘管理然后选择U ...

  8. 换ssd后Oracle,更换SSD固态硬盘后电脑无法开机原因分析和解决办法

    更换SSD固态硬盘后电脑无法开机原因分析和解决办法 有网友先自己电脑反应慢,将硬盘换成了SSD固态硬盘,自己使用Win8.1系统,重启电脑正常,但是系统更新后,电脑开机出现如下界面,提示: Windo ...

  9. 此计算机策略设置不允许安装win,系统管理员设置了系统策略,禁止进行此项安装”windows installer被禁用解决办法...

    系统管理员设置了系统策略,禁止进行此项安装"windows installer被禁用解决办法 今天想为朋友做个手机归属地批量查询系统.在网吧想装一个ACCESS. 谁知出现下面这种情况. 看 ...

最新文章

  1. qt布局中listwidget 保持固定宽度_UI设计中响应式设计实用技巧
  2. 查找文件命令find总结以及查找大文件
  3. Canal解析数据报错:column size is not match for table xxxx 59 vs 57
  4. MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理
  5. Struts2学习笔记(五)之异常处理机制
  6. python中自带的模块_python中的模块详解
  7. windows下安装consul
  8. Java学习笔记2.2.1 常量与变量 - 变量
  9. linux 从一台服务器向另台服务器复制文件
  10. 新疆有没有教电脑编程C语言,新疆学习电脑编程,新疆学电脑编程哪里好,新疆学电脑编程效果怎么样...
  11. 多摩川读写EEPROM以及并口实现
  12. STL源码剖析——stl_algobase.h
  13. 全面的在线教育直播平台是怎样的呢?
  14. 定能解决No instances available for provider
  15. javaScript中什么时候用分号;
  16. android积分墙sdk,乐点 Android SDK 积分墙开发者文档
  17. 一文带你了解Serverless架构及应用场景
  18. 让每个生命带着尊严谢幕!淘宝竟有这样一家“临终关怀”网店
  19. Android系统 屏幕最低背光亮度值/最高背光亮度值 调试
  20. 双柱状图与双折线图混合

热门文章

  1. CST2018学习笔记:一、软件启动与新项目的建立
  2. html网页的弊端,node有哪些弊端?
  3. SDOI2017 Round1解题报告
  4. python机器学习classification_report()函数 输出模型评估报告
  5. Redis - 跳跃表
  6. C++ 编程基础练习——贴现分期贷款问题
  7. linux ipv6 前缀 定义,IPv6前缀是什么?
  8. javaee学习过程
  9. 1070[Hansel and Grethel]
  10. 深入解析direct path read