程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 類似flashget的浮動窗口的實現

類似flashget的浮動窗口的實現

編輯:關於VC++

一、簡介:

象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下編譯調試成功。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved