根据一副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
分享到:
相关推荐
3. 为了使窗体在每次显示时都能自动绘制圆角,我们还需要覆盖 `CreateParams` 方法,设置 WS_EX_LAYERED 样式,这样窗体就可以透明,并且能够使用 AlphaBlend 操作: ```delphi procedure TRoundedForm....
总的来说,实现VC++对话框窗体的背景透明而控件不透明,需要利用Windows API提供的WS_EX_LAYERED窗口样式,并结合WM_PAINT和WM_NCPAINT消息的处理,以及可能的控件重绘。这个过程涉及到对Windows消息机制的深入理解...
1. 使用WS_EX_LAYERED样式后,窗口的背景不会自动绘制,需要自己处理。 2. 如果窗体包含其他控件,这些控件的透明性也需要单独处理,因为默认它们不继承父窗体的透明属性。 3. 注意处理消息WM_NCPAINT,这个消息在...
同时,需要注意的是,层叠窗口需要以WS_EX_LAYERED样式创建。 另一种方法是重写控件的画图逻辑。对于每个控件,可以通过处理WM_PAINT消息并使用GDI+或Direct2D等图形库来绘制控件的内容,确保它们在透明背景下正确...
在Windows编程中,创建具有独特视觉效果的应用程序是常见的需求,比如实现半透明窗体和不透明控件。本文将详细讲解如何利用MFC(Microsoft Foundation Classes)框架结合GDI+库来实现这样的效果,同时关注如何处理...
总结起来,使用GDI+实现PNG透明窗体(控件不透明)的关键在于启用WS_EX_LAYERED样式、正确处理Alpha通道以及在控件的Paint事件中绘制透明矩形。这个过程涉及到Windows图形绘制的底层原理,但通过正确的代码实现,...
总结来说,制作半透明窗体涉及的主要知识点包括:Windows API的使用,`WS_EX_LAYERED`窗口样式,`SetLayeredWindowAttributes`函数,以及可能的`WM_PAINT`消息处理。通过理解和掌握这些知识点,开发者能够创建出具有...
透明窗口的关键在于设置WS_EX_LAYERED窗口样式,以及使用UpdateLayeredWindow函数更新窗口的透明度和位置。 接下来,我们要创建一个自定义的Form类,重写它的OnPaintBackground方法,这样可以防止默认的背景填充。...
`WS_EX_LAYERED`允许窗体有透明度,而`WS_EX_TRANSPARENT`则使窗体背景变得透明,这样我们就可以看到窗体下面的内容。 2. **绘制形状**:使用`UpdateLayeredWindow`函数可以绘制异型窗体。你需要提供一个位图,该...
1. **设置WS_EX_LAYERED样式**:在创建窗口时,需要设置WS_EX_LAYERED窗口样式,这样窗口就能支持透明度。通过调用`CreateWindowEx`函数,传递`WS_EX_LAYERED`标志,可以实现这一目标。 2. **使用...
在MFC中,我们可以通过修改窗体的WS_EX_LAYERED样式并设置Alpha值来实现。Alpha值决定了颜色的透明度,0表示完全透明,255表示完全不透明。以下是一个简单的示例: ```cpp SetLayeredWindowAttributes(HWND(hwnd), ...
在Windows系统中,实现窗体的半透明效果主要依赖于两种技术:一个是使用`WS_EX_LAYERED`扩展窗口风格,另一个是利用`SetLayeredWindowAttributes`函数。`WS_EX_LAYERED`风格允许窗口拥有额外的透明属性,而`...
例如,我们可以添加WS_EX_LAYERED样式来实现透明效果,或者使用WS_VISIBLE样式使窗口在创建时就可见。 窗体的修饰主要通过设置窗口样式和扩展样式实现。例如,`WS_CAPTION`样式添加标题栏,`WS_MINIMIZEBOX`和`WS_...
Windows系统通过WM_PAINT消息来绘制窗口,而透明效果主要依赖于窗口类的WS_EX_LAYERED风格。当一个窗口具有此风格时,可以设置其透明度和alpha通道,从而实现不同程度的透明效果。在MFC中,可以通过重载CWnd或...
1. **创建窗口类**:在创建窗口类时,需要设置WS_EX_LAYERED扩展样式。 2. **设置透明度**:使用SetLayeredWindowAttributes函数,传入窗口句柄、颜色关键值、不透明度(alpha值)。Alpha值范围为0到255,其中0完全...
设置`WS_EX_LAYERED`样式,并使用`UpdateLayeredWindow` API函数更新窗体的透明度和颜色。透明度可以通过修改窗体的`Alpha`属性来控制,值介于0(完全透明)到255(不透明)之间。 4. 自定义控件: .NET Framework...
2. **设置窗体风格**:使用`SetWindowLong`函数,我们可以改变窗体的WS_EX_COMPOSITED、WS_EX_LAYERED等风格,以实现透明、半透明或者自定义绘图效果。 3. **应用主题**:调用`OpenThemeData`函数打开特定主题,...
1. **启用WS_EX_LAYERED样式**:在VB6.0中,我们无法直接修改窗体的样式,但可以通过API调用来实现。在窗体的Load事件中添加以下代码,以启用WS_EX_LAYERED样式: ```vb Private Declare Function SetWindowLong ...
- 首先,你需要设置窗体的WS_EX_LAYERED风格,这允许窗体拥有透明度。在WM_CREATE消息处理函数中,可以调用`SetWindowLongPtr`函数修改窗体的额外样式。 ```cpp SetWindowLongPtr(hwnd, GWL_EXSTYLE, ...
1. **CreateWindowEx()**:这个函数用于创建窗口,可以在这里设置WS_EX_LAYERED样式,这是实现透明窗口的关键。WS_EX_LAYERED风格允许我们指定窗口的透明度和颜色键。 2. **SetLayeredWindowAttributes()**:此函数...