`
csstome
  • 浏览: 1468222 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

窗体样式使用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;
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.IContainercomponents;

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);
}


WindowsFormDesignergeneratedcode #region WindowsFormDesignergeneratedcode
/**/ /// <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());
}



Form2controlFrm
= new Form2();
private void button1_Click( object sender,System.EventArgse)
... {
MessageBox.Show(controlFrm,controlFrm.textBox1.Text);

}


protected override CreateParamsCreateParams
... {
get
... {
CreateParamscp
= base .CreateParams;
cp.ExStyle
|= 0x00080000 ; // ThisformhastohavetheWS_EX_LAYEREDextendedstyle
return cp;
}

}



private void SetStyle1()
... {
Bitmapbm
= Image.FromFile( @" Green.png " ) as Bitmap;
Bitmapbm2
= Image.FromFile( @" btn.png " ) as Bitmap;

Graphicsg
= Graphics.FromImage(bm);
g.DrawImage(bm2,
20 , 20 , new Rectangle( 0 , 0 , 90 , 50 ),GraphicsUnit.Pixel);

g.DrawString(
" byjinjazz " , new Font( " Ariel " , 9 ,FontStyle.Bold), new SolidBrush(Color.Black), new PointF( 40 , 50 ));

this .SetBitmap(bm, 255 );
}

private void SetStyle2()
... {
Bitmapbm
= Image.FromFile( @" Green.png " ) as Bitmap;
Bitmapbm2
= Image.FromFile( @" btn.png " ) as Bitmap;

Graphicsg
= Graphics.FromImage(bm);
g.DrawImage(bm2,
15 , 15 , new Rectangle( 7 , 140 , 100 , 50 ),GraphicsUnit.Pixel);

g.DrawString(
" byjinjazz " , 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.EventArgse)
... {

controlFrm.Show();
SetStyle1();

// this.TopMost=true;
controlFrm.TopMost = true ;
}


private void button1_MouseEnter( object sender,EventArgse)
... {

SetStyle2();
}

private void button1_MouseLeave( object sender,EventArgse)
... {
SetStyle1();
}


public void SetBitmap(Bitmapbitmap, byte opacity)
... {
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException( " Thebitmapmustbe32pppwithalpha-channel. " );

// Theideiaofthisisverysimple,
// 1.CreateacompatibleDCwithscreen;
// 2.Selectthebitmapwith32bppwithalpha-channelinthecompatibleDC;
// 3.CalltheUpdateLayeredWindow.

IntPtrscreenDc
= Win32.GetDC(IntPtr.Zero);
IntPtrmemDc
= Win32.CreateCompatibleDC(screenDc);
IntPtrhBitmap
= IntPtr.Zero;
IntPtroldBitmap
= IntPtr.Zero;

try
... {
hBitmap
= bitmap.GetHbitmap(Color.FromArgb( 0 )); // grabaGDIhandlefromthisGDI+bitmap
oldBitmap = Win32.SelectObject(memDc,hBitmap);

Win32.Sizesize
= new Win32.Size(bitmap.Width,bitmap.Height);
Win32.PointpointSource
= new Win32.Point( 0 , 0 );
Win32.PointtopPos
= new Win32.Point(Left,Top);
Win32.BLENDFUNCTIONblend
= 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); // ThedocumentationsaysthatwehavetousetheWindows.DeleteObject...butsincethereisnosuchmethodIusethenormalDeleteObjectfromWin32GDIandit'sworkingfinewithoutanyresourceleak.
Win32.DeleteObject(hBitmap);
}

Win32.DeleteDC(memDc);
}

}



private System.Windows.Forms.Buttonbutton1;

private void Form1_MouseDown( object sender,System.Windows.Forms.MouseEventArgse)
... {
Win32.ReleaseCapture();
Win32.SendMessage(
this .Handle.ToInt32(),Win32.WM_SysCommand,Win32.SC_MOVE, 0 );
}

ht
分享到:
评论

相关推荐

    制作半透明窗口-WS_EX_LAYERED-SetWindowLong

    介绍编写半透明窗口的源代码,API的NO—MFC,JUST DO IT!

    duilib半透明异形窗口_修改WM_PAINT

    1.当前窗口样式必须是WS_EX_LAYERED,不能是WS_CHILD. 2.所有的WS_CHILD样式的子窗口不能正常显示. 3.系统接管几乎所有WM_PANIT消息, 除了我们主动调用Invalidate()产生的WM_PAINT.(这点很重要) 4.BeginPaint与...

    透明窗体透明控件

    Private Const WS_EX_LAYERED = &H80000; Private Const GWL_EXSTYLE = (-20) Private Const LWA_ALPHA = &H2; Private Const LWA_COLORKEY = &H1; Private Sub asPopup1_Click(Cancel As Boolean) If Text1....

    LayeredWindow.rar

    最基础的分层窗口代码,显示一张图片,涉及的主要API为:UpdateLayeredWindow。创建窗口时设置窗口类型WS_EX_LAYERED。

    信息通信网络概论课件:Chapter_2__Application_and_Layered_Architectures.ppt

    信息通信网络概论课件:Chapter_2__Application_and_Layered_Architectures.ppt

    Delphi添加图层蒙版.rar

    Delphi添加图层蒙版,运行本程序... SetWindowLong(Handle, GWL_EXSTYLE, OldStyle or WS_EX_LAYERED Or WS_EX_TRANSPARENT);  bTrans := 128;  SetLayeredWindowAttributes(Handle, 0, bTrans, LWA_ALPHA);  end;

    [API] 透明提示框

    Public Const WS_EX_NOPARENTNOTIFY As Long = &H4& Public Const WS_EX_TOPMOST As Long = &H8& Public Const WS_EX_TRANSPARENT As Long = &H20& Public Const WS_GROUP As Long = &H20000 Public Const WS_...

    支持标准Winform控件的Layered窗体

    支持标准Winform控件的透明窗体,支持半透明PNG背景图,非双窗体技术的另一种实现方案。 含源代码

    VC 窗口用图片做阴影边框

    原理:使用SetWindowLong 设置WS_EX_LAYERED,将对话框设置成层级窗口。 分为两层: 后层为背景窗口,使用GDI+显示图片。显示成功后再用UpdateLayeredWindow函数进行透明处理。并在这个对话框中定义一个子对话框对象...

    VC模仿酷狗7(Kugou7) UI界面源码,有动画效果

     实现方法:给窗口加上WS_EX_LAYERED样式,使用Gdiplus画出图片,然后UpdateLayeredWindow。处理WM_MOUSEHOVER、WM_MOUSELEAVE消息,鼠标进入或移出画出不同状态。  注意事项:只是实现初步模拟而已,未响应子控件...

    VC模仿酷狗7(Kugou7) UI界面源码,有动画效果.rar

    实现方法:给窗口加上WS_EX_LAYERED样式,使用Gdiplus画出图片,然后UpdateLayeredWindow。处理WM_MOUSEHOVER、WM_MOUSELEAVE消息,鼠标进入或移出画出不同状态。 注意事项:只是实现初步模拟而已,未响应子控件...

    layered窗体阴影

    layered窗体通过GDI+绘制带有alpha通道的图片实现窗体阴影,该案例基于MFC和ATL实现

    页游浏览工具源码

    public const int WS_EX_LAYERED = 0x80000; //窗口具有透眀属性(Win2000)以上 public const int WS_EX_NOACTIVATE = 0x8000000; //窗口不会变成前台窗口(Win2000)以上 [DllImport("user32", EntryPoint = ...

    Disk-Class-Driver.zip_disk class_layered file system

    磁盘类驱动程序用于与磁盘设备以及相应的端口驱动程序。磁盘类驱动是分层高于端口驱动程序和管理磁盘设备,不论他们的总线类型。这个驱动程序连接到磁盘设备枚举所有的存储端口驱动程序。这个司机暴露所需要的功能,...

    仿Win7半透明窗口效果、简单模拟CButton控件

    用的透明窗口风格WS_EX_LAYERED ,然后通过UpdateLayeredWindow 函数对窗口皮肤已经按钮图像进行贴图,所谓的按钮并非控件,而是通过判断区域来模拟的按钮响应。程序性能上有很大不足,希望共同交流.

    C# 鼠标穿透窗体功能的实现方法

    代码如下: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_...

    MFC实现透明窗口

    实现方法:首先用SetWindowLong为窗口添加WS_EX_LAYERED属性,再用SetLayeredWindowAttributes设置窗口透明。

    半透明窗体的vb瞬间网络流量统计程序

     按照微软的要求,透明窗体窗体在创建时应使用WS_EX_LAYERED参数(用CreateWindowEx),或者在创建后设置该参数(用SetWindowLong),我选用后者。全部函数,其中hwnd是透明窗体的句柄,crKey为颜色值,bAlpha是...

Global site tag (gtag.js) - Google Analytics