MFC拖动窗体时使窗体半透明

如是大家细心的话,在使用“Virtual Drive Manager”也就是一个非常小的虚拟光驱的时候,在它的设置里有一个“启用窗口的 Alpha 混合半透明效果”功能。这个功能很友善,就是在你想拖动窗体的时候,窗体会自动的渐隐,等到你松开窗口的时候,窗体就恢复到不透明的状态。下面是 该功能的截图今天要做的就是让我们的程序也实现这个功能。

 

OK先分析一下它的功能。

1.当点击标题栏的时候,让窗口半透明

2.当松开标题栏的时候,窗口自动恢复不透明的状态

明天了原理之后我们就可以很简单的来实现这个功能了,点击标题栏我们可以用“ON_WM_NCLBUTTONDOWN”这个事件来触发。当松开标题栏的时候可以使用“ON_WM_NCLBUTTONUP”事件。但现在有问题了,在我写的过程中“ON_WM_NCLBUTTONUP”当松开对标题栏的点击时程序不会触发“ON_WM_NCLBUTTONUP”事件。所以这程序就渐接的转换为使程序响应“ON_WM_NCLBUTTONUP”事件。

 

值得说的是可以用ON_WM_SYSCOMMAND事件来得到“ON_WM_NCLBUTTONUP” ,好了,下面让我们来实现这个小程序吧

 

首先先建立一个“基本对话框”程序。有没有关于对话框都一样,如是有的话就省略后面写ON_WM_SYSCOMMAND这个事件了。OK,我就建立一个不要关于对话框的程序

首先先添加“ON_WM_NCLBUTTONDOWN”,这个事件在VC6.0是没有办法找到怎么添加的,所以我们要手动添加。在

  1. BEGIN_MESSAGE_MAP(CMyDlg, CDialog)  
  2.     //{{AFX_MSG_MAP(CMyDlg)  
  3.     ......  
  4.     ON_WM_NCLBUTTONDOWN()   //添加鼠标按下标题栏时的事件  
  5.     ......  
  6.     //}}AFX_MSG_MAP  
  7. END_MESSAGE_MAP()  

添加好之后再添加对应的函数响应

  1. //  
  2. // 添加渐隐函数——按下时  
  3. void down(void)  
  4. {  
  5.     for (int m_int=255;m_int>=128;m_int-=7){  
  6.         SetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE,   
  7.             GetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE) | 0x80000);   
  8.   
  9.         HINSTANCE hInst=LoadLibrary("User32.DLL");   
  10.         if(hInst)   
  11.         {   
  12.             typedef BOOL     (WINAPI * MYFUNC)(HWND,COLORREF,BYTE,DWORD);   
  13.             MYFUNC fun=NULL;   
  14.               
  15.             //取得SetLayeredWindowAttributes函数指针   
  16.             fun=(MYFUNC)GetProcAddress(hInst,"SetLayeredWindowAttributes");   
  17.             if(fun)   
  18.                 fun(AfxGetMainWnd()->m_hWnd,0,m_int,2);   
  19.             FreeLibrary(hInst);   
  20.         }   
  21.         Sleep(10);  
  22.     }  
  23.   
  24. }  
  25. //  
  26. // 响应点击标题栏函数  
  27. void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)  
  28. {  
  29.     if (nHitTest == HTCAPTION)        
  30.         hDownThread=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)down,NULL,NULL,NULL);  
  31.     CDialog::OnNcLButtonDown(nHitTest, point);  
  32. }  

再在对应的Dlg.h中声明 OnNcLButtonDown 函数为事件函数

[c-sharp]  view plain copy print ?
  1. afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);  

这样编译一下就可以现在点击标题栏时的半透明窗口了。

OK,下面以相同的方法添加“ON_WM_NCLBUTTONUP”和“ON_WM_SYSCOMMAND” 由于内容基本一样,所以就不写打了,直接给代码

[c-sharp]  view plain copy print ?
  1. //  
  2. // ON_WM_SYSCOMMAND事件响应函数  
  3. void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)  
  4. {  
  5.     CDialog::OnSysCommand(nID, lParam);  
  6.     //   手动添加WM_NCLBUTTONUP事件  
  7.     if((nID&0xFFF0)==SC_MOVE) PostMessage(WM_NCLBUTTONUP,nID,lParam);  
  8. }  
  9.   
  10. HANDLE hDownThread=NULL;    //按下时的线程句柄  
  11. //  
  12. // 添加渐隐函数——松开时  
  13. void Up(void)  
  14. {  
  15.     WaitForSingleObject(hDownThread,INFINITE);  
  16.     for (int m_int=128;m_int<=255;m_int+=7){  
  17.         SetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE,   
  18.             GetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE) | 0x80000);   
  19.         HINSTANCE hInst=LoadLibrary("User32.DLL");   
  20.         if(hInst)   
  21.         {   
  22.             typedef BOOL     (WINAPI * MYFUNC)(HWND,COLORREF,BYTE,DWORD);   
  23.             MYFUNC fun=NULL;   
  24.               
  25.             //取得SetLayeredWindowAttributes函数指针   
  26.             fun=(MYFUNC)GetProcAddress(hInst,"SetLayeredWindowAttributes");   
  27.             if(fun)   
  28.                 fun(AfxGetMainWnd()->m_hWnd,0,m_int,2);   
  29.             FreeLibrary(hInst);   
  30.         }   
  31.         Sleep(10);  
  32.     }  
  33. }  
  34. //  
  35. // 响应松开标题栏时的函数  
  36. void CMyDlg::OnNcLButtonUp(UINT nHitTest, CPoint point)  
  37. {  
  38.     CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)Up,NULL,NULL,NULL);  
  39.     CDialog::OnNcLButtonUp(nHitTest,   point);  
  40. }  

OK,编译一下看看自己的程序是什么样子的吧,是不是感觉它很“温和”呢。呵呵。。

下面是我的程序截图

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值