一、简介:
象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.
int
nY = bmp.bmHeight;
12.
//根据位图的大小移动窗口
13.
MoveWindow(0,0,nX,nY);
14.
m_Logo.MoveWindow(0,0,nX,nY);
15.
CenterWindow();
2、前端显示。
1.
//通过SetWindowsPos函数将窗口前端显示。
2.
::SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
3、在客户区内按下鼠标左键可以随意拖动窗口的位置。响应WM_HITTEST函数,当鼠标左键按下并在客户区内,返回HTCAPTION,欺骗Windows,达到跟在标题栏拖动窗口一样的效果。
01.
UINT
CFloatWnd::OnNcHitTest(CPoint pt)
02.
{
03.
UINT
nHitTest = CDialog::OnNcHitTest(pt);
04.
05.
if
(nHitTest == HTCLIENT && ::GetAsyncKeyState(MK_LBUTTON) < 0)
// 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0
06.
07.
nHitTest = HTCAPTION;
08.
09.
return
nHitTest;
10.
}
4、改变窗口的透明度。将窗口样式设置为WS_EX_LAYERED,并调用SetLayeredWindowAttributes函数来改变窗口的透明度。WS_EX_LAYERED可能没定义,我们可以直接取值0x80000。
1.
//加入WS_EX_LAYERED扩展属性
2.
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中载入。
01.
//更新窗口透明度的代码,其中iTransparent为透明度。
02.
void
CFloatWnd::OnUpdateTransparent(
int
iTransparent)
03.
{
04.
HINSTANCE
hInst = LoadLibrary(
"User32.DLL"
);
05.
if
(hInst)
06.
{
07.
typedef
BOOL
(WINAPI *SLWA)(
HWND
,
COLORREF
,
BYTE
,
DWORD
);
08.
SLWA pFun = NULL;
09.
//取得SetLayeredWindowAttributes函数指针
10.
pFun = (SLWA)GetProcAddress(hInst,
"SetLayeredWindowAttributes"
);
11.
if
(pFun)
12.
{
13.
pFun(m_hWnd,0,iTransparent,2);
14.
}
15.
FreeLibrary(hInst);
16.
}
17.
}
5、双击可以将主窗口激活并显示。由于WM_HITTEST消息的影响,我们双击鼠标的时候产生的是WM_NCLBUTTONDBLCLK消息,而不是WM_LBUTTONDBLCLK消息。
01.
void
CFloatWnd::OnNcLButtonDblClk(
UINT
nFlags, CPoint point)
02.
{
03.
// TODO: Add your message handler code here and/or call default
04.
CWnd *pParent = GetParent();
05.
ASSERT(pParent);
06.
//显示窗口
07.
if
(!pParent->IsWindowVisible())
08.
pParent->ShowWindow(SW_SHOW);
09.
//置窗口到最前面
10.
pParent->SetForegroundWindow();
11.
12.
CDialog::OnNcLButtonDblClk(nFlags, point);
13.
}
关于调节透明度的Slider使用,也写了一些代码,一并贴出来,供大家参考。
01.
void
CMainDlg::OnHScroll(
UINT
nSBCode,
UINT
nPos, CScrollBar* pScrollBar)
02.
{
03.
// TODO: Add your message handler code here and/or call default
04.
//得到Slider的位置
05.
int
iCurPos = m_Slider.GetPos();
06.
//得到最大值、最小值,及页大小
07.
int
nMax = m_Slider.GetRangeMax();
08.
int
nMin = m_Slider.GetRangeMin();
09.
int
nPageSize = m_Slider.GetPageSize();
10.
11.
switch
(nSBCode)
12.
{
13.
case
SB_LINELEFT:
14.
if
(iCurPos > nMin)
15.
iCurPos --;
16.
break
;
17.
case
SB_LINERIGHT:
18.
if
(iCurPos < nMax)
19.
iCurPos ++;
20.
break
;
21.
case
SB_PAGELEFT:
22.
if
(iCurPos > nMin)
23.
iCurPos = max(nMin,iCurPos - nPageSize);
24.
break
;
25.
case
SB_PAGERIGHT:
26.
if
(iCurPos < nMax)
27.
iCurPos = min(nMax,iCurPos + nPageSize);
28.
break
;
29.
case
SB_THUMBTRACK:
30.
iCurPos = nPos;
31.
break
;
32.
case
SB_THUMBPOSITION:
33.
iCurPos = nPos;
34.
break
;
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