根据一副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
分享到:
相关推荐
介绍编写半透明窗口的源代码,API的NO—MFC,JUST DO IT!
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....
最基础的分层窗口代码,显示一张图片,涉及的主要API为:UpdateLayeredWindow。创建窗口时设置窗口类型WS_EX_LAYERED。
信息通信网络概论课件:Chapter_2__Application_and_Layered_Architectures.ppt
Delphi添加图层蒙版,运行本程序... SetWindowLong(Handle, GWL_EXSTYLE, OldStyle or WS_EX_LAYERED Or WS_EX_TRANSPARENT); bTrans := 128; SetLayeredWindowAttributes(Handle, 0, bTrans, LWA_ALPHA); end;
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控件的透明窗体,支持半透明PNG背景图,非双窗体技术的另一种实现方案。 含源代码
原理:使用SetWindowLong 设置WS_EX_LAYERED,将对话框设置成层级窗口。 分为两层: 后层为背景窗口,使用GDI+显示图片。显示成功后再用UpdateLayeredWindow函数进行透明处理。并在这个对话框中定义一个子对话框对象...
实现方法:给窗口加上WS_EX_LAYERED样式,使用Gdiplus画出图片,然后UpdateLayeredWindow。处理WM_MOUSEHOVER、WM_MOUSELEAVE消息,鼠标进入或移出画出不同状态。 注意事项:只是实现初步模拟而已,未响应子控件...
实现方法:给窗口加上WS_EX_LAYERED样式,使用Gdiplus画出图片,然后UpdateLayeredWindow。处理WM_MOUSEHOVER、WM_MOUSELEAVE消息,鼠标进入或移出画出不同状态。 注意事项:只是实现初步模拟而已,未响应子控件...
layered窗体通过GDI+绘制带有alpha通道的图片实现窗体阴影,该案例基于MFC和ATL实现
public const int WS_EX_LAYERED = 0x80000; //窗口具有透眀属性(Win2000)以上 public const int WS_EX_NOACTIVATE = 0x8000000; //窗口不会变成前台窗口(Win2000)以上 [DllImport("user32", EntryPoint = ...
磁盘类驱动程序用于与磁盘设备以及相应的端口驱动程序。磁盘类驱动是分层高于端口驱动程序和管理磁盘设备,不论他们的总线类型。这个驱动程序连接到磁盘设备枚举所有的存储端口驱动程序。这个司机暴露所需要的功能,...
用的透明窗口风格WS_EX_LAYERED ,然后通过UpdateLayeredWindow 函数对窗口皮肤已经按钮图像进行贴图,所谓的按钮并非控件,而是通过判断区域来模拟的按钮响应。程序性能上有很大不足,希望共同交流.
代码如下: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_...
实现方法:首先用SetWindowLong为窗口添加WS_EX_LAYERED属性,再用SetLayeredWindowAttributes设置窗口透明。
按照微软的要求,透明窗体窗体在创建时应使用WS_EX_LAYERED参数(用CreateWindowEx),或者在创建后设置该参数(用SetWindowLong),我选用后者。全部函数,其中hwnd是透明窗体的句柄,crKey为颜色值,bAlpha是...