半透明信息显示浮动窗口的实现

转自:半透明信息显示浮动窗口的实现

分类: 高级界面 2010-05-14 09:48 9281人阅读 评论(100) 收藏 举报

       实现目的

       在一些画图软件中,经常需要向用户展示鼠标移动到的位置的对象的一些参数信息。此时,完成一个交互性友好的信息显示界面就相当的重要了。因为一个软件的好坏,在用户的眼中,第一感觉甚至是第一重要的就是视觉效果和可操作性。当然,软件本身的稳定性和效率也很重要。特别对于产品性的软件,在用户展示时,一个优秀的界面效果可以大大加深软件在用户心里的印象分。

       功能简介

       本功能是作者根据自身软件在用户实际使用过程中对交互性的更高要求而开发的。浮动窗口其实是一个对话框,设置为无标题的风格,然后进行自绘制而成。能够根据需要显示的内容自动调整窗口的大小,保证正好能够容纳需要显示的内容。如以下效果:

       图中黄色条为栏目分隔,同时显示其下内容所属的信息域。如图中表示下方信息为台风即时预报信息的内容。下方信息分成两栏,栏间绘制线条进行分割。左侧为信息标题,右侧为信息内容。比如台风名称是奥麦斯。

       如果鼠标移动的位置,同时选中多项内容,那么,提示信息可以同时包括多个栏目,如下图:

 

       本图中包括两个栏目,即本公司船位置信息和美气导的等压线信息。从理论上讲,本功能可以支持任意多的栏目,前提是你的显示器能够容纳得下。

       整个界面的效果是半透明的。包括透明度,字体大小和信息内容的颜色都可以由用户自行定义,配置界面如下:

       透明度范围为0-255;背景色列表框是作者在博客中已提供的一个自定义的线条、填充和颜色选择列表控件。

       修改完成后,可以改变浮动窗口的显示效果,比如一种修改后的效果:

       这样,即使用户对浮动窗口内容的展示方式不满意,那么也完全可以由用户自行定义自己喜欢的风格。当然,在此基础上,可以进一步扩大自定义的范围。本例中,栏目分割条的背景色和信息内容标题文字的颜色是固定的,信息内容文字的颜色是背景色的反色,这些都可以考虑加入到自定义项中。

代码实现

 

以下是消息提示项的数据结构:

 

  1. typedef struct _MSG_TIP//消息提示数据项描述信息   
  2.   
  3. {  
  4.   
  5.        CString sMsgItemName;                  //信息标题   
  6.   
  7.        CString sMsgItemInfo;               //信息内容   
  8.   
  9.        COLORREF nInfoShowColor; //显示颜色(此项值目前暂时没有使用,原意是使每个栏目的文字颜色均可自定义;因为考虑到设定的颜色可能和背景色冲突,因此目前文字颜色使用背景色的反色)   
  10.   
  11. }MSG_TIP;  
  12.   
  13. typedef CArray<MSG_TIP,MSG_TIP&> CMsgTipArray;//消息提示内容  

 

头文件,MsgTipDlg.h

  1. #if !defined(AFX_MSGTIPDLG_H__9759E9A8_93DE_4003_BCB2_87F390641270__INCLUDED_)   
  2. #define AFX_MSGTIPDLG_H__9759E9A8_93DE_4003_BCB2_87F390641270__INCLUDED_   
  3.   
  4. #if _MSC_VER > 1000   
  5. #pragma once   
  6. #endif // _MSC_VER > 1000   
  7. // MsgTipDlg.h : header file   
  8. //   
  9.   
  10. /   
  11. // CMsgTipDlg dialog   
  12.   
  13. class CMsgTipDlg : public CDialog  
  14. {  
  15. // Construction   
  16. public:  
  17.     CMsgTipDlg(CWnd* pParent = NULL);   // standard constructor   
  18.     CSize ShowMsgTip(CMsgTipArray &arMsgTip); //供外部函数传递需要显示的内容,并计算尺寸   
  19.     void UpdateTrans();     //修改透明度等配置参数       
  20.     void DrawMsgTip();      //绘制提示信息   
  21. // Dialog Data   
  22.     //{{AFX_DATA(CMsgTipDlg)   
  23.     enum { IDD = IDD_MSGTIP_DLG };  
  24.     //}}AFX_DATA   
  25.   
  26. // Overrides   
  27.     // ClassWizard generated virtual function overrides   
  28.     //{{AFX_VIRTUAL(CMsgTipDlg)   
  29.     public:  
  30.     virtual BOOL PreTranslateMessage(MSG* pMsg);  
  31.     protected:  
  32.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support   
  33.     //}}AFX_VIRTUAL   
  34.   
  35. // Implementation   
  36. protected:  
  37.     CMsgTipArray m_arMsgTip;    //提示信息数组   
  38.     CFont   m_MsgTipFont;       //用于消息提示的字体   
  39.     int     m_nTipNameWidth;    //标题名最大宽度,决定竖线绘制位置   
  40.     int     m_nRowHeight;       //行高,决定横线绘制位置   
  41. private:  
  42.     void DrawGrid(CDC *pDC,CRect &rc);                      //绘制网格   
  43.     void DrawMsgTip(CDC *pDC,CPoint topPos,MSG_TIP &mt);    //绘制提示信息(某一条)   
  44.     void DrawMsg(CDC *pDC);                                 //绘制信息   
  45.       
  46.     // Generated message map functions   
  47.     //{{AFX_MSG(CMsgTipDlg)   
  48.     virtual BOOL OnInitDialog();  
  49.     afx_msg void OnPaint();  
  50.     //}}AFX_MSG   
  51.     DECLARE_MESSAGE_MAP()  
  52. };  
  53.   
  54. //{{AFX_INSERT_LOCATION}}   
  55. // Microsoft Visual C++ will insert additional declarations immediately before the previous line.   
  56.   
  57. #endif // !defined(AFX_MSGTIPDLG_H__9759E9A8_93DE_4003_BCB2_87F390641270__INCLUDED_)  

CPP文件,MsgTipDlg.cpp

  1. // MsgTipDlg.cpp : implementation file   
  2. //   
  3.   
  4. #include "stdafx.h"   
  5. #include "MsgTipDlg.h"   
  6.   
  7. #ifdef _DEBUG   
  8. #define new DEBUG_NEW   
  9. #undef THIS_FILE   
  10. static char THIS_FILE[] = __FILE__;  
  11. #endif   
  12.   
  13. /   
  14. // CMsgTipDlg dialog   
  15.   
  16.   
  17. CMsgTipDlg::CMsgTipDlg(CWnd* pParent /*=NULL*/)  
  18.     : CDialog(CMsgTipDlg::IDD, pParent)  
  19. {  
  20.     //{{AFX_DATA_INIT(CMsgTipDlg)   
  21.     //}}AFX_DATA_INIT   
  22. }  
  23.   
  24.   
  25. void CMsgTipDlg::DoDataExchange(CDataExchange* pDX)  
  26. {  
  27.     CDialog::DoDataExchange(pDX);  
  28.     //{{AFX_DATA_MAP(CMsgTipDlg)   
  29.     //}}AFX_DATA_MAP   
  30. }  
  31.   
  32.   
  33. BEGIN_MESSAGE_MAP(CMsgTipDlg, CDialog)  
  34.     //{{AFX_MSG_MAP(CMsgTipDlg)   
  35.     ON_WM_PAINT()  
  36.     //}}AFX_MSG_MAP   
  37. END_MESSAGE_MAP()  
  38.   
  39. /   
  40. // CMsgTipDlg message handlers   
  41.   
  42. BOOL CMsgTipDlg::OnInitDialog()   
  43. {  
  44.     CDialog::OnInitDialog();  
  45.     m_MsgTipFont.CreateFont(  
  46.         theApp.m_sysINIFile.GetMsgTipConfig().nMsgTipFontSize,// nHeight   
  47.         0,                         // nWidth   
  48.         0,                         // nEscapement   
  49.         0,                         // nOrientation   
  50.         FW_SEMIBOLD,                  // nWeight   
  51.         FALSE,                     // bItalic   
  52.         FALSE,                     // bUnderline   
  53.         0,                         // cStrikeOut   
  54.         DEFAULT_CHARSET,              // nCharSet   
  55.         OUT_DEFAULT_PRECIS,        // nOutPrecision   
  56.         CLIP_DEFAULT_PRECIS,       // nClipPrecision   
  57.         DEFAULT_QUALITY,           // nQuality   
  58.         DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily   
  59.         "Times New Roman");//"MS Sans Serif");//Arial   
  60.     m_nTipNameWidth = 0;  
  61.     m_nRowHeight = 0;     
  62.       
  63.     SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,  
  64.     GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);  
  65.     //WS_EX_LAYERED   
  66.     HINSTANCE hInst = LoadLibrary("User32.DLL");   
  67.     if(hInst)   
  68.     {   
  69.         typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);   
  70.         MYFUNC fun = NULL;  
  71.         //取得SetLayeredWindowAttributes函数指针    
  72.         fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");  
  73.         if(fun)  
  74.             //fun(this->GetSafeHwnd(),0,400,2);    
  75.             fun(this->GetSafeHwnd(),0,theApp.m_sysINIFile.GetMsgTipConfig().nMsgTipTrans,2);  
  76.         FreeLibrary(hInst);   
  77.     }  
  78.   
  79.     return TRUE;  // return TRUE unless you set the focus to a control   
  80.                   // EXCEPTION: OCX Property Pages should return FALSE   
  81. }  
  82.   
  83. //供外部函数传递需要显示的内容,同时获得需要显示的内容的尺寸,以决定本界面的大小   
  84. CSize CMsgTipDlg::ShowMsgTip(CMsgTipArray &arMsgTip)  
  85. {  
  86.     CSize size(0,0);  
  87.     //   
  88.     m_arMsgTip.Copy(arMsgTip);  
  89.   
  90.     int nSize = m_arMsgTip.GetSize();  
  91.     if(nSize == 0)  
  92.         return size;  
  93.   
  94.     CDC *pDC = GetDC();  
  95.     pDC->SelectObject(&m_MsgTipFont);  
  96.     int nMaxNameLen = 0;  
  97.     int nMaxInfoLen = 0;  
  98.     int nMaxTitleLen = 0;  
  99.     CSize sz;  
  100.     for(int i=0; i<nSize; i++)  
  101.     {  
  102.         MSG_TIP mt = m_arMsgTip.GetAt(i);  
  103.         if(mt.nInfoShowColor == -1)  
  104.         {  
  105.             ::GetTextExtentPoint32(pDC->m_hDC, mt.sMsgItemName,mt.sMsgItemName.GetLength(),&sz);  
  106.             if(sz.cx > nMaxTitleLen)  
  107.                 nMaxTitleLen = sz.cx;  
  108.             continue;  
  109.         }  
  110.         ::GetTextExtentPoint32(pDC->m_hDC, mt.sMsgItemName,mt.sMsgItemName.GetLength(),&sz);  
  111.         if(sz.cx > nMaxNameLen)  
  112.             nMaxNameLen = sz.cx;  
  113.         if(mt.sMsgItemInfo.GetLength() == 0)  
  114.             continue;  
  115.         else  
  116.         {  
  117.             ::GetTextExtentPoint32(pDC->m_hDC, mt.sMsgItemInfo,mt.sMsgItemInfo.GetLength(),&sz);  
  118.             if(sz.cx > nMaxInfoLen)  
  119.                 nMaxInfoLen = sz.cx;  
  120.         }  
  121.   
  122.     }  
  123.     m_nTipNameWidth = nMaxNameLen + 8;  
  124.     m_nRowHeight = sz.cy + 4;  
  125.     //   
  126.     int nTitleWidth = nMaxTitleLen;  
  127.     size.cx = m_nTipNameWidth + nMaxInfoLen+5;  
  128.     if(size.cx < nTitleWidth)  
  129.         size.cx = nTitleWidth;  
  130.     size.cx += 5;  
  131.     size.cy = m_nRowHeight * nSize;  
  132.     ReleaseDC(pDC);  
  133.     return size;  
  134. }  
  135.   
  136. void CMsgTipDlg::OnPaint()   
  137. {  
  138.     CPaintDC dc(this); // device context for painting   
  139.       
  140.     DrawMsg(&dc);  
  141.       
  142.     // Do not call CDialog::OnPaint() for painting messages   
  143. }  
  144.   
  145. void CMsgTipDlg::DrawMsg(CDC *pDC)  
  146. {  
  147.     CRect rc;  
  148.     GetClientRect(&rc);  
  149.     CDC memDC;  
  150.     memDC.CreateCompatibleDC(pDC);  
  151.     CBitmap bmp;  
  152.     bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());  
  153.     CBitmap *pOldBmp = memDC.SelectObject(&bmp);  
  154.     memDC.FillSolidRect(rc,theApp.m_sysINIFile.GetMsgTipConfig().nMsgTipBkColor);  
  155.     CFont *pOldFont = memDC.SelectObject(&m_MsgTipFont);  
  156.       
  157.     DrawGrid(&memDC,rc);  
  158.     //   
  159.     int nSize = m_arMsgTip.GetSize();  
  160.     CPoint topPos(0,0);  
  161.     for(int i=0; i<nSize; i++)  
  162.     {  
  163.         MSG_TIP mt = m_arMsgTip.GetAt(i);  
  164.         DrawMsgTip(&memDC,topPos,mt);  
  165.         topPos.y += m_nRowHeight;  
  166.     }  
  167.     pDC->BitBlt(0, 0, rc.Width(),rc.Height(), &memDC, 0, 0, SRCCOPY) ;  
  168.     pDC->SelectObject(pOldBmp);  
  169.     pDC->SelectObject(pOldFont);  
  170.     bmp.DeleteObject();  
  171.     memDC.DeleteDC();  
  172. }  
  173.   
  174. void CMsgTipDlg::DrawMsgTip(CDC *pDC, CPoint topPos, MSG_TIP &mt)  
  175. {  
  176.     int nBkMode = pDC->SetBkMode(TRANSPARENT);  
  177.     if(mt.nInfoShowColor == -1)  
  178.     {  
  179.         CRect rc;  
  180.         GetClientRect(&rc);  
  181.         CRect rowRc(topPos,CSize(rc.Width(),m_nRowHeight+2));  
  182.         pDC->FillSolidRect(rowRc,COLOR_BUFF);  
  183.         COLORREF nTC = pDC->SetTextColor(COLOR_MAGENTA);  
  184.         pDC->TextOut(topPos.x+4,topPos.y+4,mt.sMsgItemName);  
  185.         pDC->SetTextColor(nTC);  
  186.     }  
  187.     else  
  188.     {  
  189.         COLORREF nTC = pDC->SetTextColor(COLOR_MAGENTA);  
  190.         pDC->TextOut(topPos.x+4,topPos.y+4,mt.sMsgItemName);  
  191.         nTC = pDC->SetTextColor(COLOR_WHITE-theApp.m_sysINIFile.GetMsgTipConfig().nMsgTipBkColor);//mt.nInfoShowColor);//   
  192.         pDC->TextOut(topPos.x+m_nTipNameWidth+8,topPos.y+4,mt.sMsgItemInfo);  
  193.         pDC->SetTextColor(nTC);  
  194.     }  
  195.     pDC->SetBkMode(nBkMode);  
  196. }  
  197.   
  198. void CMsgTipDlg::DrawGrid(CDC *pDC,CRect &rc)  
  199. {  
  200.     CPen pen(PS_SOLID,1,COLOR_BUFF);  
  201.     CPen *pOldPen = pDC->SelectObject(&pen);  
  202.     CPoint ptTop(m_nTipNameWidth,0);  
  203.     CPoint ptBottom(m_nTipNameWidth,rc.bottom);  
  204.     pDC->MoveTo(ptTop);  
  205.     pDC->LineTo(ptBottom);  
  206.     //   
  207.     int nSize = m_arMsgTip.GetSize();  
  208.     for(int i=0; i<nSize-1; i++)  
  209.     {  
  210.         CPoint ptLeft(0,(m_nRowHeight)*(i+1)+2);  
  211.         CPoint ptRight(rc.right,(m_nRowHeight)*(i+1)+2);  
  212.         pDC->MoveTo(ptLeft);  
  213.         pDC->LineTo(ptRight);  
  214.     }  
  215.     pDC->SelectObject(pOldPen);  
  216. }  
  217.   
  218. void CMsgTipDlg::UpdateTrans()  
  219. {  
  220.     HINSTANCE hInst = LoadLibrary("User32.DLL");   
  221.     if(hInst)   
  222.     {   
  223.         typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);   
  224.         MYFUNC fun = NULL;  
  225.         //取得SetLayeredWindowAttributes函数指针    
  226.         fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");  
  227.         if(fun)  
  228.             //fun(this->GetSafeHwnd(),0,400,2);    
  229.             fun(this->GetSafeHwnd(),0,theApp.m_sysINIFile.GetMsgTipConfig().nMsgTipTrans,2);  
  230.         FreeLibrary(hInst);   
  231.     }  
  232.     if(m_MsgTipFont.m_hObject != NULL)  
  233.     {  
  234.         m_MsgTipFont.DeleteObject();  
  235.         m_MsgTipFont.CreateFont(  
  236.             theApp.m_sysINIFile.GetMsgTipConfig().nMsgTipFontSize,// nHeight   
  237.             0,                         // nWidth   
  238.             0,                         // nEscapement   
  239.             0,                         // nOrientation   
  240.             FW_SEMIBOLD,                  // nWeight   
  241.             FALSE,                     // bItalic   
  242.             FALSE,                     // bUnderline   
  243.             0,                         // cStrikeOut   
  244.             DEFAULT_CHARSET,              // nCharSet   
  245.             OUT_DEFAULT_PRECIS,        // nOutPrecision   
  246.             CLIP_DEFAULT_PRECIS,       // nClipPrecision   
  247.             DEFAULT_QUALITY,           // nQuality   
  248.             DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily   
  249.             "Times New Roman");//Arial  }   
  250.     }  
  251. }  
  252.   
  253. void CMsgTipDlg::DrawMsgTip()  
  254. {  
  255.     CDC *pDC = GetDC();  
  256.     DrawMsg(pDC);  
  257.     ReleaseDC(pDC);  
  258. }  
  259.   
  260. //鼠标不能移动到本界面,一旦移动到本界面,立即隐藏   
  261. BOOL CMsgTipDlg::PreTranslateMessage(MSG* pMsg)   
  262. {  
  263.     if(pMsg->message == WM_MOUSEMOVE)  
  264.     {  
  265.         ShowWindow(SW_HIDE);  
  266.     }  
  267.     return CDialog::PreTranslateMessage(pMsg);  
  268. }  

外部调用:

  1. //显示提示信息   
  2. void CPetrelProView::ShowMsgTip(BOOL bShow,CMsgTipArray &arMsgTip)  
  3. {  
  4.     if(m_pMsgTipDlg == NULL)  
  5.     {  
  6.         m_pMsgTipDlg = new CMsgTipDlg();  
  7.         m_pMsgTipDlg->Create(IDD_MSGTIP_DLG,this);  
  8.     }  
  9.     if(!bShow)  
  10.     {  
  11.         m_pMsgTipDlg->ShowWindow(SW_HIDE);  
  12.     }  
  13.     else  
  14.     {  
  15.         CSize size = m_pMsgTipDlg->ShowMsgTip(arMsgTip);  
  16.         if(size.cx == 0)  
  17.             return;  
  18.         CPoint pt;  
  19.         GetCursorPos(&pt);  
  20.         CRect rc(pt,size);  
  21.         rc.OffsetRect(15,20);  
  22.         CRect mRc;  
  23.         GetWindowRect(&mRc);  
  24.         if(rc.bottom > mRc.bottom)  
  25.             rc.OffsetRect(0,mRc.bottom-rc.bottom-5);  
  26.         if(rc.right > mRc.right)  
  27.         {  
  28.             rc.OffsetRect(-rc.Width()-30,0);  
  29.         }  
  30.         m_pMsgTipDlg->SetWindowPos(&wndTop,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW|SWP_NOACTIVATE);  
  31.         m_pMsgTipDlg->DrawMsgTip();  
  32.     }  
  33. }  

那么,剩下的工作,就是需要在每个实体类中增加类似这样的函数:

    CMsgTipArray arMsgTip;
    pDoc->m_pShipMan->GetMsgTipInfo(arMsgTip);
在OnMouseMove事件中,从各个实体类中获取对象选中的情况。

如下是一个例子:

  1. void CShip::GetMsgTipInfo(CMsgTipArray &arMsgTip)  
  2. {  
  3.     MSG_TIP mt;  
  4.     mt.nInfoShowColor = -1;  
  5.     mt.sMsgItemName = "它船位置信息";  
  6.     mt.sMsgItemInfo = "";  
  7.     arMsgTip.Add(mt);  
  8.     mt.sMsgItemInfo = m_ShipBaseInfo.sEngName;  
  9.     mt.sMsgItemName = "船舶名称";  
  10.     mt.nInfoShowColor = COLOR_GRASS;  
  11.     arMsgTip.Add(mt);  
  12.     mt.sMsgItemInfo = m_ShipBaseInfo.sMMSIID;  
  13.     mt.sMsgItemName = "MMSI";  
  14.     arMsgTip.Add(mt);  
  15.     CString sDate = m_ShipBaseInfo.tNowReptTime.Format("%Y-%m-%d %H:%M:%S");  
  16.     mt.sMsgItemInfo = sDate;  
  17.     mt.sMsgItemName = "报告时间";  
  18.     arMsgTip.Add(mt);  
  19.     CString sLat = CoordFormatDouble2Str(m_ShipBaseInfo.nowPos.dLatitude,true,theApp.m_sysINIFile.GetLatLongConfig().eLatLongFmt);  
  20.     CString sLong = CoordFormatDouble2Str(m_ShipBaseInfo.nowPos.dLongitude,false,theApp.m_sysINIFile.GetLatLongConfig().eLatLongFmt);  
  21.     mt.sMsgItemInfo = sLat;  
  22.     mt.sMsgItemName = "纬度";  
  23.     arMsgTip.Add(mt);  
  24.     mt.sMsgItemInfo = sLong;  
  25.     mt.sMsgItemName = "经度";  
  26.     arMsgTip.Add(mt);  
  27.     if(m_ShipBaseInfo.fNowCOG > 359.9)  
  28.         mt.sMsgItemInfo = "NA";  
  29.     else  
  30.         mt.sMsgItemInfo.Format("%.1f°",m_ShipBaseInfo.fNowCOG);  
  31.     mt.sMsgItemName = "航向";  
  32.     arMsgTip.Add(mt);  
  33.     if(m_ShipBaseInfo.fNowSOG > 102)  
  34.         mt.sMsgItemInfo = "NA";  
  35.     else  
  36.         mt.sMsgItemInfo.Format("%.1f",m_ShipBaseInfo.fNowSOG);  
  37.     mt.sMsgItemName = "航速";  
  38.     arMsgTip.Add(mt);  
  39.     if(m_ShipBaseInfo.wTrueHeading == 511)  
  40.         mt.sMsgItemInfo = "NA";  
  41.     else  
  42.         mt.sMsgItemInfo.Format("%d°",m_ShipBaseInfo.wTrueHeading);  
  43.     mt.sMsgItemName = "船首向";  
  44.     arMsgTip.Add(mt);  
  45.     if(abs(m_ShipBaseInfo.lROT) >= 720)  
  46.         mt.sMsgItemInfo = "NA";  
  47.     else  
  48.         mt.sMsgItemInfo.Format("%d°/分",m_ShipBaseInfo.lROT);  
  49.     mt.sMsgItemName = "转向率";  
  50.     arMsgTip.Add(mt);  
  51.     mt.sMsgItemName = "船位来源";  
  52.     mt.sMsgItemInfo = m_ShipBaseInfo.sPosFromName;  
  53.     if(mt.sMsgItemInfo.GetLength() == 0)  
  54.         mt.sMsgItemInfo = m_ShipBaseInfo.sPosFromCode;  
  55.     arMsgTip.Add(mt);  
  56. }  

     以上工作即可实现一个浮动的鼠标移动选中的对象的半透明的提示窗。当鼠标移开或者移动到提示窗上时,提示窗将立刻隐藏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值