好库网 好库网首页 | 我的好库
好饱的专栏

透明控件的实现方法

发布者:好饱
发布日期:2011/2/21 22:10:54   更新日期:2011/2/21 22:27:19
阅读次数:6116
评分:4.80
介绍:在界面开发中,你需要实现一些炫的效果,你经常会遇到使控件透明方面的问题。在本文中 我提供了一个实现透明控件的方法。源代码包含基于Win32 API的类CTransparentHelper, 可以在MFC,ATL,WTL,Win32应用程序中或其它框架下使用。
正文:
介绍
在界面开发中,你需要实现一些炫的效果,你经常会遇到使控件透明方面的问题。在本文中
我提供了一个实现透明控件的方法。源代码包含基于Win32 API的类CTransparentHelper,
可以在MFC,ATL,WTL,Win32应用程序中或其它框架下使用。如果你有好的意见、BUG、问题
请发邮件给我,我会更新版本。你也可以访问我的技术博客 http://blog.uieasy.com/

下载源代码

介绍

在界面开发中,你需要实现一些炫的效果,你经常会遇到使控件透明方面的问题。在本文中

我提供了一个实现透明控件的方法。源代码包含基于Win32 API的类CTransparentHelper,

可以在MFC,ATL,WTL,Win32应用程序中或其它框架下使用。如果你有好的意见、BUG、问题

请发邮件给我,我会更新版本。你也可以访问我的技术博客 http://blog.uieasy.com/

 

背景

我写这个代码是因为我需要一些透明的控件,如:按钮、滑动控件、进度条等。

我发现当父窗口或控件移动时一些效果无效;当你在可改变大小的对话框中使用透明控件这将是一个问题。因此,我写了CTransparentHelper来解决。当MoveWindow调用后会有一个平滑的透明效果。

 

特点

1.没有依赖其它框架

2.能在不同类型的控件中使用

3.能在多层透明中使用

4.代码易用

 

使用代码

在介绍如何使用源代码前,我建议用内存DC存储父对话框的背景DC。这样使子控件的透明比如容易实现也提高了绘图效率。更多内容,请参考源代码。

 

包含 "TransparentHelper.h"

在需要透明显示的控件文件中 #include "TransparentHelper.h"

然后添加一个CTransparentHelper类型的对象.

#pragma once

#include"TransparentHelper.h"
// CSliderCtrlEx

class CSliderCtrlEx : public CSliderCtrl
{
   .........
   CTransparentHelper m_objTrans;
}
初始化CTransparentHelper对象
void CSliderCtrlEx::PreSubclassWindow()
{

   // TODO: Add your specialized code here and/or call the base class
   .......

   CSliderCtrl::PreSubclassWindow();
   m_objTrans.Install( GetSafeHwnd());
   ......
}
 在需要的时候调用 CTransparentHelper的TransparentBk函数
 
BOOL CSliderCtrlEx::OnSliderDrawChannel( CDC* pDC,
   CRect& rect, UINT nState)
{
   ......
   if ( m_objTrans.IsValid() )
   {
      m_objTrans.TransparentBk( pDC->GetSafeHdc(), GetSafeHwnd());
   }
   .........
   return TRUE;
}
在控件的父窗口中添加代码
有时,父窗口是一个对话框,我需要处理WM_TRANSPARENT_BK消息,该消息从透明控件发送,目的是恢复DC。

LRESULT CTransparentControlDlg::OnTransaprentBk( WPARAM wParam,
                                                 LPARAM lParam)
{
   HDC hdc = ( HDC)wParam;
   HWND hwnd = ( HWND)lParam;

   CTransparentHelper::OnTranparentControl( m_pMemDC->GetSafeHdc(), 
                                          (WPARAM)hdc, (LPARAM)hwnd);
   return TRUE;
}
注:m_pMemDC是对话框的内存DC,当对话框尺寸变化时,m_pMemDC将会被改变。

背景更改时通知子控件
当对话框的内存DC更改,它必须所有透明的子控件。
void CTransparentControlDlg::BuildBkDC()
{
   //rebuild the background dc
   ........
   //when the parent dialog's background is rebuilt,
   //notify the child which has an transparent tag.
   CTransparentHelper::NotifyTransparentChild( GetSafeHwnd());
}
WM_NOTIFY_TRANSPARENT消息
透明控件需要处理 WM_NOTIFY_TRANSPARENT消息,当背景改变,父窗口将发送该消息。
注:对于一些使用某些绘图函数的控件(例如:NM_CUSTOMDRAW),Invalidate不会导致真正的重绘。
因此,我添加 WM_NOTIFY_TRANSPARENT消息使其兼容。如果透明控件在调用Invalidate后能够自己
重绘则不需要处理该消息。
LRESULT CSliderCtrlEx::OnNotifyTransparent( WPARAM wParam,
                                            LPARAM lParam)
{
   if ( ::IsWindowEnabled( GetSafeHwnd()))
   {
      ::EnableWindow( GetSafeHwnd(),FALSE);
      ::EnableWindow( GetSafeHwnd(),TRUE);
   }
   else
   {
      ::EnableWindow( GetSafeHwnd(),TRUE);
      ::EnableWindow( GetSafeHwnd(),FALSE);
   }
   //This operation is for the repaint of slider control,
   //because Invalidate can't bring the NM_CUSTOMDRAW message.
   //M..., this may not the best method to solve the problem.
   //If you have another method, please tell me.

   return TRUE;
}
关于作者
拥有8年软件架构开发经验,擅长用C++进行WINDOWS应用开发。

评论 [发表评论]
账号 密码 还没帐号呢,现在注册一个?

免责声明:好库网所展示的信息由买卖双方自行提供,其真实性、准确性和合法性由信息发布人负责。好库网不提供任何保证,并不承担任何法律责任。