我在写播放器时发现在网上可以说是没有很好的开源的进度条,我也曾找到过几个,但是他们都不能满足我的要求,而且使用的时候精度也很差,不是很精确。在我前面写的文章中也有我自己封装的进度条控件,但是那是我在06年时作品,水平有限烂的要命,同样有我上面所说的问题。为了能有一个比较好的控件最后还是在08年时费了点时间重新封装。今天我把它贴出来给初学者学习一下。
我把这个控件封成了两个版本,一个MFC版,一个ATL版。控件可以显示下载进度,播放进度,和原始状态。精度也非常的高。下面是我对控件的截图
代码下载http://download.csdn.net/source/2237018
在示例工程中的MKBitSlider.h MKBitSlider.cpp就是控件的实现文件。这个示例我们还是用ATL控件来演示,控件的建立在前面我们已经讲过,在此不再做细讲,在控件中有一个CConmandWnd的类,这个是一个窗口类,我们就在这个窗口中演示控件。在这个类的头文件中加入
CMKBitSlider m_cSliderVideo; // 视频滑动条
这个就是我们的进度条的变量声明。然在窗口初如中加入进度条的创建如下:
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CAxDialogImpl<CConmandWnd>::OnInitDialog(uMsg, wParam, lParam, bHandled);
RECT rc = {0, 500, 500, 520};
m_cSliderVideo.Create(m_hWnd,rc,NULL,WS_CHILD|WS_VISIBLE);
m_cSliderVideo.SetBitmap( IDB_MP_CHANNEL, IDB_MP_CHANNEL_ACTIVE,IDB_MP_CHANNEL_PROGRESS, IDB_MP_THUMB );
m_cSliderVideo.SetRange( 0, 1000 );
m_cSliderVideo.SetPos( 0 );
m_cSliderVideo.ShowWindow(SW_SHOW);
SetTimer(1,1000,NULL);
return 1; // Let the system set the focus
}
这样进度条就能显出来了。当我们点击进度时进度条会发送一个消息,拖动thumb也会不断的向父类发送消息,为了能接到这两个消息我们要加入两个接收函数。先加消息映射如下
MESSAGE_HANDLER(WM_BITMAPSLIDER_MOVED, OnBitmapSliderMoved)
MESSAGE_HANDLER(WM_BITMAPSLIDER_MOVING, OnBitmapSliderMoving)
第一个是在点击后放开左键时才会收到的,同样在拖动后放时也能收到。而第二个在拖动时会把每个点都发送过来。这样我们就可以根据当前位置的变化再做相就的操作。下面是两个函数的实现。
LRESULT CConmandWnd::OnBitmapSliderMoved(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
int iPos = lParam;
return 0;
}
LRESULT CConmandWnd::OnBitmapSliderMoving(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
int iPos = lParam;
return 0;
}
lParam参数就是当前位置。需要说明的是如果在当前的窗口中要有多个这样的进度条那我们怎么办呢,这个好说,wParam参数是发送消息者的控件ID,所以我们可以用下面的语句来判断是不是我们想要操作控件的消息:
if(wParam == m_cSliderVideo.GetDlgCtrlID())
{//进行我们想要的操作}
为了让我们的控件能动起来我们加入一个timer来模拟外部设置:
LRESULT CConmandWnd::OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// TODO: Add your message handler code here and/or call default
if( m_cSliderVideo.m_hWnd ){
static int iPos = 0;
if( iPos < 1000 ){
//这里表示当我们是P2P下载时可能下载的数据是多个小的区域,所以你可以把多个区间组成一个MAP表来设入,
CMKBitSlider::GM_MapArea AreaMap;
for(int i = 0; i < iPos; i += 5){
AreaMap[i] = i + 5; //表示从i 到i+5的一个小区间
}
iPos += 20;
m_cSliderVideo.PutDownloadInfo(AreaMap,1000);
}
static int iNewPos = 0;
if( iNewPos < 1000 ){
m_cSliderVideo.SetPos(iNewPos += 4 );
}
}
return 0;
}
好了可以,你进行编译吧。
用IE调试WndCtrl.htm页就会看我们一开出现的样子,而且是一个动态的图。
这个控件还支持在两端显示两个按钮,这样你要在你的背景图上事先画好,同样要在初始化时设置按钮的宽度
m_cSliderVideo.SetButtonWidth( iWidth );
我只所以展示这个控件不仅是要大家会用,更重要的是给大家一个学习的例子,这样大家可以参考里面的方法自己去学习如何封装精美控件。