• 类似flashget的浮动窗口的实现


    一、简介:

      象flashget、迅雷、BT等都有浮动窗口,能详细地显示下载的详细信息,该类型的窗口有一下几个特点:1、窗口无标题栏,窗口的大小跟位图一样大。2、前端显示。3、在客户区内按下鼠标左键可以随意拖动窗口的位置。4、可以改变窗口的透明度。5、双击可以将主窗口激活,并显示。下面就该类型窗口的各个功能实现予以说明。

    二、代码的详细说明:

      1、窗口无标题栏,窗口的大小跟位图一样大。建立一个对话框资源,设置为POPUP类型,并取消Title Bar属性。在上面插入一个图片控件,设置为导入的位图。

    //得到位图
     CBitmap m_Bitmap;
     HBITMAP hBitmap = m_Logo.GetBitmap();
     ASSERT(hBitmap);
     //得到位图的信息
     m_Bitmap.Attach(hBitmap);
     BITMAP bmp;
     m_Bitmap.GetBitmap(&bmp);
     //得到位图的大小
     int nX = bmp.bmWidth;
     int nY = bmp.bmHeight;
     //根据位图的大小移动窗口
     MoveWindow(0,0,nX,nY);
     m_Logo.MoveWindow(0,0,nX,nY);
     CenterWindow();

      2、前端显示。

    //通过SetWindowsPos函数将窗口前端显示。
     ::SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);

      3、在客户区内按下鼠标左键可以随意拖动窗口的位置。响应WM_HITTEST函数,当鼠标左键按下并在客户区内,返回HTCAPTION,欺骗Windows,达到跟在标题栏拖动窗口一样的效果。

    UINT CFloatWnd::OnNcHitTest(CPoint pt)
    {
     UINT nHitTest = CDialog::OnNcHitTest(pt);
    
     if (nHitTest == HTCLIENT && ::GetAsyncKeyState(MK_LBUTTON) < 0) // 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0
    
      nHitTest = HTCAPTION;
    
     return nHitTest;
    }

      4、改变窗口的透明度。将窗口样式设置为WS_EX_LAYERED,并调用SetLayeredWindowAttributes函数来改变窗口的透明度。WS_EX_LAYERED可能没定义,我们可以直接取值0x80000。

    //加入WS_EX_LAYERED扩展属性
     SetWindowLong(m_hWnd,GWL_EXSTYLE,GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);

    BOOL SetLayeredWindowAttributes(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags);
    hwnd是要改变的窗口,当dwFlags为LWA_ALPHA(0x2)时,crKey参数没用,bAlpha为透明度,取值在0~255之间。该函数要从User.dll中载入。

    //更新窗口透明度的代码,其中iTransparent为透明度。
    void CFloatWnd::OnUpdateTransparent(int iTransparent)
    {
     HINSTANCE hInst = LoadLibrary("User32.DLL");
     if(hInst)
     {
      typedef BOOL (WINAPI *SLWA)(HWND,COLORREF,BYTE,DWORD);
      SLWA pFun = NULL;
      //取得SetLayeredWindowAttributes函数指针 
      pFun = (SLWA)GetProcAddress(hInst,"SetLayeredWindowAttributes");
      if(pFun)
      {
       pFun(m_hWnd,0,iTransparent,2);
      }
      FreeLibrary(hInst); 
     }
    }

      5、双击可以将主窗口激活并显示。由于WM_HITTEST消息的影响,我们双击鼠标的时候产生的是WM_NCLBUTTONDBLCLK消息,而不是WM_LBUTTONDBLCLK消息。

    void CFloatWnd::OnNcLButtonDblClk(UINT nFlags, CPoint point) 
    {
     // TODO: Add your message handler code here and/or call default 
     CWnd *pParent = GetParent();
     ASSERT(pParent);
     //显示窗口
     if(!pParent->IsWindowVisible())
      pParent->ShowWindow(SW_SHOW);
     //置窗口到最前面
     pParent->SetForegroundWindow();
    
     CDialog::OnNcLButtonDblClk(nFlags, point);
    }

      关于调节透明度的Slider使用,也写了一些代码,一并贴出来,供大家参考。

    void CMainDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
     // TODO: Add your message handler code here and/or call default
     //得到Slider的位置
     int iCurPos = m_Slider.GetPos(); 
     //得到最大值、最小值,及页大小
     int nMax = m_Slider.GetRangeMax();
     int nMin = m_Slider.GetRangeMin();
     int nPageSize = m_Slider.GetPageSize();
    
     switch(nSBCode)
     {
     case SB_LINELEFT:
      if(iCurPos > nMin)
       iCurPos --;
      break;
     case SB_LINERIGHT:
      if(iCurPos < nMax)
       iCurPos ++;
      break;
     case SB_PAGELEFT:
      if(iCurPos > nMin)
       iCurPos = max(nMin,iCurPos - nPageSize);
      break;
     case SB_PAGERIGHT:
      if(iCurPos < nMax)
       iCurPos = min(nMax,iCurPos + nPageSize);
      break;
     case SB_THUMBTRACK:
      iCurPos = nPos;
      break;
     case SB_THUMBPOSITION:
      iCurPos = nPos;
      break;  
     }
     //设置Slider位置
     m_Slider.SetPos(iCurPos);
     //更新透明度
     pFloatWnd->OnUpdateTransparent(iCurPos);
     
     CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
    }

      至于该窗口的右键菜单,窗口的显示与隐藏,程序的退出等简单代码我就不多介绍了。

    三、该程序在Windows xp sp2和Visual C++6.0下编译调试成功。

    源代码下载!

    摘自:VC知识库

    作者:BuildNewApp
    出处:http://syxchina.cnblogs.comBuildNewApp.com
    本文版权归作者、博客园和百度空间共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则作者会诅咒你的。
    如果您阅读了我的文章并觉得有价值请点击此处,谢谢您的肯定1。
  • 相关阅读:
    单调栈
    P1164 小A点菜
    P1156 垃圾陷阱
    P1140 相似基因
    P1136 迎接仪式
    P1133 教主的花园
    P1131 [ZJOI2007]时态同步
    P1130 红牌
    利用SQLite在android上实现增删改查
    利用SQLite在android上创建数据库
  • 原文地址:https://www.cnblogs.com/syxchina/p/2197406.html
Copyright © 2020-2023  润新知