类似flashget的浮动窗口的实现
一、简介: 象flashget、迅雷、BT等都有浮动窗口,能详细地显示下载的详细信息,该类型的窗口有一下几个特点:1、窗口无标题栏,窗口的大小跟位图一样大。2、前端显示。3、在客户区内按下鼠标左键可以随意拖动窗口的位置。4、可以改变窗口的透明度。5、双击可以将主窗口激活,并显示。下面就该类型窗口的各个功能实现予以说明。 二、代码的详细说明: 1、窗口无标题栏,窗口的大小跟位图一样大。建立一个对话框资源,设置为POPUP类型,并取消Title Bar属性。在上面插入一个图片控件,设置为导入的位图。 01.
//得到位图
02.
CBitmap m_Bitmap;
03.
HBITMAP ?hBitmap = m_Logo.GetBitmap();
04.
ASSERT(hBitmap);
05.
//得到位图的信息
06.
m_Bitmap.Attach(hBitmap);
07.
BITMAP bmp;
08.
m_Bitmap.GetBitmap(&bmp);
09.
//得到位图的大小
10.
int?
nX = bmp.bmWidth;
11.
nY = bmp.bmHeight;
12.
//根据位图的大小移动窗口
13.
MoveWindow(0,nX,nY);
14.
m_Logo.MoveWindow(0,nY);
15.
CenterWindow();
2、前端显示。 1.
//通过SetWindowsPos函数将窗口前端显示。
2.
::SetWindowPos(m_hWnd,HWND_TOPMOST,SWP_NOMOVE | SWP_NOSIZE);???
3、在客户区内按下鼠标左键可以随意拖动窗口的位置。响应WM_HITTEST函数,当鼠标左键按下并在客户区内,返回HTCAPTION,欺骗Windows,达到跟在标题栏拖动窗口一样的效果。 UINT?
CFloatWnd::OnNcHitTest(CPoint pt)
{
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( 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" (pFun)
pFun(m_hWnd,iTransparent,2);
}
FreeLibrary(hInst);
16.
17.
}
5、双击可以将主窗口激活并显示。由于WM_HITTEST消息的影响,我们双击鼠标的时候产生的是WM_NCLBUTTONDBLCLK消息,而不是WM_LBUTTONDBLCLK消息。 CFloatWnd::OnNcLButtonDblClk(
nFlags,CPoint point)
// TODO: Add your message handler code here and/or call default
CWnd *pParent = GetParent();
ASSERT(pParent);
//显示窗口
(!pParent->IsWindowVisible())
pParent->ShowWindow(SW_SHOW);
//置窗口到最前面
pParent->SetForegroundWindow();
?
CDialog::OnNcLButtonDblClk(nFlags,point);
}
关于调节透明度的Slider使用,也写了一些代码,一并贴出来,供大家参考。 CMainDlg::OnHScroll(
nSBCode,? nPos,CScrollBar* pScrollBar)
//得到Slider的位置
iCurPos = m_Slider.GetPos();???
//得到最大值、最小值,及页大小
nMax = m_Slider.GetRangeMax();
nMin = m_Slider.GetRangeMin();
nPageSize = m_Slider.GetPageSize();
switch
(nSBCode)
case?
SB_LINELEFT:
(iCurPos > nMin)
iCurPos --;
break
;
SB_LINERIGHT:
18.
(iCurPos < nMax)
19.
iCurPos ++;
20.
21.
SB_PAGELEFT:
22.
23.
iCurPos = max(nMin,iCurPos - nPageSize);
24.
25.
SB_PAGERIGHT:
26.
27.
iCurPos = min(nMax,iCurPos + nPageSize);
28.
29.
SB_THUMBTRACK:
30.
iCurPos = nPos;
31.
;
32.
SB_THUMBPOSITION:
33.
iCurPos = nPos;
34.
;?????
35.
}
36.
//设置Slider位置
37.
m_Slider.SetPos(iCurPos);
38.
//更新透明度
39.
pFloatWnd->OnUpdateTransparent(iCurPos);
40.
41.
CDialog::OnHScroll(nSBCode,nPos,pScrollBar);
42.
}
至于该窗口的右键菜单,窗口的显示与隐藏,程序的退出等简单代码我就不多介绍了。 三、该程序在Windows xp sp2和Visual C++6.0下编译调试成功。 这个文档是在“vc知识库”里面看到的。里面还有其源程序:http://www.vckbase.com/index.php/cv/1270 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |