首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  界面/窗口  |  对话框   


类似Flashget的浮动窗口的实现


原作者:苍竹先生    源出处:VC知识库    发布者:施昌权    发布类型:转载    发布日期:2008-08-15


        一、简介:
        象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下编译调试成功。

点击这里下载源码

 

关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号