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

窗体样式使用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
分享到:
评论

相关推荐

    Delphi 中制作几何形状的窗体 圆角

    3. 为了使窗体在每次显示时都能自动绘制圆角,我们还需要覆盖 `CreateParams` 方法,设置 WS_EX_LAYERED 样式,这样窗体就可以透明,并且能够使用 AlphaBlend 操作: ```delphi procedure TRoundedForm....

    VC中对话框窗体背景透明而控件不透明

    总的来说,实现VC++对话框窗体的背景透明而控件不透明,需要利用Windows API提供的WS_EX_LAYERED窗口样式,并结合WM_PAINT和WM_NCPAINT消息的处理,以及可能的控件重绘。这个过程涉及到对Windows消息机制的深入理解...

    C++BUILDER BCB透明窗体

    1. 使用WS_EX_LAYERED样式后,窗口的背景不会自动绘制,需要自己处理。 2. 如果窗体包含其他控件,这些控件的透明性也需要单独处理,因为默认它们不继承父窗体的透明属性。 3. 注意处理消息WM_NCPAINT,这个消息在...

    窗体半透明控件不透明

    同时,需要注意的是,层叠窗口需要以WS_EX_LAYERED样式创建。 另一种方法是重写控件的画图逻辑。对于每个控件,可以通过处理WM_PAINT消息并使用GDI+或Direct2D等图形库来绘制控件的内容,确保它们在透明背景下正确...

    半透明窗体不透明控件

    在Windows编程中,创建具有独特视觉效果的应用程序是常见的需求,比如实现半透明窗体和不透明控件。本文将详细讲解如何利用MFC(Microsoft Foundation Classes)框架结合GDI+库来实现这样的效果,同时关注如何处理...

    PNG透明窗体(控件不透明)

    总结起来,使用GDI+实现PNG透明窗体(控件不透明)的关键在于启用WS_EX_LAYERED样式、正确处理Alpha通道以及在控件的Paint事件中绘制透明矩形。这个过程涉及到Windows图形绘制的底层原理,但通过正确的代码实现,...

    半透明窗体的制作实例.

    总结来说,制作半透明窗体涉及的主要知识点包括:Windows API的使用,`WS_EX_LAYERED`窗口样式,`SetLayeredWindowAttributes`函数,以及可能的`WM_PAINT`消息处理。通过理解和掌握这些知识点,开发者能够创建出具有...

    C# 完美实现窗口以透明PNG绘制_控件不透明.zip

    透明窗口的关键在于设置WS_EX_LAYERED窗口样式,以及使用UpdateLayeredWindow函数更新窗口的透明度和位置。 接下来,我们要创建一个自定义的Form类,重写它的OnPaintBackground方法,这样可以防止默认的背景填充。...

    C#异型窗体的简单实现

    `WS_EX_LAYERED`允许窗体有透明度,而`WS_EX_TRANSPARENT`则使窗体背景变得透明,这样我们就可以看到窗体下面的内容。 2. **绘制形状**:使用`UpdateLayeredWindow`函数可以绘制异型窗体。你需要提供一个位图,该...

    通过GDI绘制透明窗体

    1. **设置WS_EX_LAYERED样式**:在创建窗口时,需要设置WS_EX_LAYERED窗口样式,这样窗口就能支持透明度。通过调用`CreateWindowEx`函数,传递`WS_EX_LAYERED`标志,可以实现这一目标。 2. **使用...

    MFC半透明窗体 不透明控件

    在MFC中,我们可以通过修改窗体的WS_EX_LAYERED样式并设置Alpha值来实现。Alpha值决定了颜色的透明度,0表示完全透明,255表示完全不透明。以下是一个简单的示例: ```cpp SetLayeredWindowAttributes(HWND(hwnd), ...

    VC半透明窗体可调整透明度

    在Windows系统中,实现窗体的半透明效果主要依赖于两种技术:一个是使用`WS_EX_LAYERED`扩展窗口风格,另一个是利用`SetLayeredWindowAttributes`函数。`WS_EX_LAYERED`风格允许窗口拥有额外的透明属性,而`...

    WinAPI函数修饰程序窗体

    例如,我们可以添加WS_EX_LAYERED样式来实现透明效果,或者使用WS_VISIBLE样式使窗口在创建时就可见。 窗体的修饰主要通过设置窗口样式和扩展样式实现。例如,`WS_CAPTION`样式添加标题栏,`WS_MINIMIZEBOX`和`WS_...

    MFC窗体透明显示

    Windows系统通过WM_PAINT消息来绘制窗口,而透明效果主要依赖于窗口类的WS_EX_LAYERED风格。当一个窗口具有此风格时,可以设置其透明度和alpha通道,从而实现不同程度的透明效果。在MFC中,可以通过重载CWnd或...

    半透明窗体

    1. **创建窗口类**:在创建窗口类时,需要设置WS_EX_LAYERED扩展样式。 2. **设置透明度**:使用SetLayeredWindowAttributes函数,传入窗口句柄、颜色关键值、不透明度(alpha值)。Alpha值范围为0到255,其中0完全...

    winform创建不规则窗体和控件源码

    设置`WS_EX_LAYERED`样式,并使用`UpdateLayeredWindow` API函数更新窗体的透明度和颜色。透明度可以通过修改窗体的`Alpha`属性来控制,值介于0(完全透明)到255(不透明)之间。 4. 自定义控件: .NET Framework...

    美化窗体及控件 QQ2009样式

    2. **设置窗体风格**:使用`SetWindowLong`函数,我们可以改变窗体的WS_EX_COMPOSITED、WS_EX_LAYERED等风格,以实现透明、半透明或者自定义绘图效果。 3. **应用主题**:调用`OpenThemeData`函数打开特定主题,...

    VB窗体透明

    1. **启用WS_EX_LAYERED样式**:在VB6.0中,我们无法直接修改窗体的样式,但可以通过API调用来实现。在窗体的Load事件中添加以下代码,以启用WS_EX_LAYERED样式: ```vb Private Declare Function SetWindowLong ...

    PNG透明窗体全攻略(控件不透明)可实现不规则窗体.

    - 首先,你需要设置窗体的WS_EX_LAYERED风格,这允许窗体拥有透明度。在WM_CREATE消息处理函数中,可以调用`SetWindowLongPtr`函数修改窗体的额外样式。 ```cpp SetWindowLongPtr(hwnd, GWL_EXSTYLE, ...

    vc中透明窗体实例制作,api函数

    1. **CreateWindowEx()**:这个函数用于创建窗口,可以在这里设置WS_EX_LAYERED样式,这是实现透明窗口的关键。WS_EX_LAYERED风格允许我们指定窗口的透明度和颜色键。 2. **SetLayeredWindowAttributes()**:此函数...

Global site tag (gtag.js) - Google Analytics