关于WS_EX_LAYERED的思考

带有WS_EX_LAYERED风格的窗口也就是我们说的分层窗口,主要是为了了实现异形窗口和窗口整体透明。

若果要实现异形窗口则必须要设置这个风格,然后使用UpdateLayeredWindow函数来绘制,这样才能将控件的透明色和窗口后面的图像进行融合,从而绘制出带有透明效果的窗口

而要实现窗口的整体透明,则需要首先设置WS_EX_LAYERED风格,然后调用SetLayeredWindowAttribute函数设置透明度


以上所说的要想搞和透明相关的东西则必须设置这个分层风格,注意:

1、一旦调用UpdateLayeredWindow函数,WM_PAINT消息将失效,如果界面需要更新,则需要自己调用UpdateLayeredWindow函数

2、子窗口无法应用WS_EX_LAYERED风格,如果应用这个风格,将无法实现透明效果。也就是说这个窗口必须是非WS_CHILD;


那么要求子窗口是异形的或者整体透明的,那么只能去掉WS_CHILD风格,然后MOVE到一定位置,在父窗口移动的时候跟随移动。

首先在创建窗口的时候不能指定CHILD属性,但必须指定父窗口句柄到createwindowEx函数,否则会出现创建的窗口属于桌面,那样的话你点击主程序窗口,这个子窗口会躲到后面去,也相对于桌面上两个互不相干的窗口一样,那样就失去意义了,所以代码如下:

if(!m_pLSideBtn->Create(m_hWnd/*主程序窗口句柄*/, NULL,  WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW | WS_EX_LAYERED))
{
delete m_pLSideBtn;
m_pLSideBtn = NULL;
return false;
}

然后再主窗口的MOVE里面:

::SetWindowPos(m_hWnd, 
HWND_TOP, 
pt.x, 
pt.y, 
0, 
0,
SWP_SHOWWINDOW | SWP_NOSIZE);

注意这边是相对于桌面的移动,创建的窗口用SPY看,父窗口就是主程序窗口,拥有者也是主程序窗口,样式的话没有CHILD,这样就让子窗口支持透明和异形,试运行后效果不错。

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这条代码设置了一个窗口的扩展样式,其中包含了 WS_EX_TOPMOST、WS_EX_LAYEREDWS_EX_TRANSPARENT 和 WS_EX_TOOLWINDOW 四种样式。其中,WS_EX_TOPMOST 表示这个窗口总在最上面,WS_EX_LAYERED 表示这个窗口使用颜色加权混合方式绘制,WS_EX_TRANSPARENT 表示这个窗口是透明的,WS_EX_TOOLWINDOW 表示这个窗口是一个工具窗口。这条代码将扩展样式设置为这些样式的组合,从而使得鼠标可以穿过窗体,直接点击桌面。但是,这条代码并没有提供取消鼠标穿透的方法。如果想要取消鼠标穿透,你可以将窗口的扩展样式设置为不包含 WS_EX_TRANSPARENT 的样式,这样就可以解除鼠标穿透效果了。 ### 回答2: 使用SetWindowLong函数来设置窗口的扩展样式,包括WS_EX_TOPMOST、WS_EX_LAYEREDWS_EX_TRANSPARENT和WS_EX_TOOLWINDOW。其中WS_EX_TOPMOST将窗口设置为最顶层,WS_EX_LAYERED使窗口支持透明效果,WS_EX_TRANSPARENT使窗口透明,并且允许鼠标穿透,WS_EX_TOOLWINDOW将窗口标识为工具窗口。 通过使用以上代码,可以使鼠标可以穿过窗体,直接点击桌面。但是在没有其他的代码进行修改的情况下,无法取消鼠标穿透。如果要取消鼠标穿透,需要进行进一步的操作。 可以使用以下代码取消鼠标穿透功能: SetWindowLong(_hwnd, GWL_EXSTYLE, GetWindowLong(_hwnd, GWL_EXSTYLE) & ~WS_EX_TRANSPARENT); 通过使用GetWindowLong函数获取当前窗口的扩展样式,并且取消WS_EX_TRANSPARENT标志位,最后通过SetWindowLong函数重新设置窗口的扩展样式。 注意:以上操作仅针对当前窗口进行修改,如果要取消其他窗口的鼠标穿透功能,需要在相应的窗口句柄上进行相同的操作。 ### 回答3: 使用SetWindowLong函数设置窗体的扩展样式,包括WS_EX_TOPMOST(窗体置顶)、WS_EX_LAYERED(窗体透明)、WS_EX_TRANSPARENT(鼠标穿透)和WS_EX_TOOLWINDOW(工具窗口)。通过将这些扩展样式使用按位或运算符合并在一起,通过_hwnd参数指定窗体的句柄,可以使鼠标可以穿过窗体直接点击桌面。 然而,根据提供的代码,没有提供取消鼠标穿透的方法。调用SetWindowLong函数并设置新的窗体扩展样式后,将无法通过类似的方式来取消鼠标穿透。如果要取消鼠标穿透,需要重新调用SetWindowLong函数,并在GWL_EXSTYLE参数中使用原始窗体的扩展样式,而不包括WS_EX_TRANSPARENT。这将覆盖之前设置的样式,从而实现取消鼠标穿透的效果。 具体的代码示例如下: ```c++ // 设置窗体的扩展样式,包括鼠标穿透 SetWindowLong(_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW); // 要取消鼠标穿透,重新设置窗体的扩展样式,将原始样式设置回去(不包括WS_EX_TRANSPARENT) SetWindowLong(_hwnd, GWL_EXSTYLE, originalExStyle); ``` 需注意的是,originalExStyle代表窗体在调用SetWindowLong函数前的扩展样式,需要在调用该函数之前保留该值,以便在取消鼠标穿透时恢复窗体的原始样式。 希望以上解答能对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值