MFC – Progress control

Progress bar

Progressbar được sử dụng để hiển thị tiến độ của 1 việc gì đó. Ví dụ như download, copy tài liệu, burn đĩa CD,..

Sau đây, sẽ là bài hướng dẫn tạo MFC application hiển thị giờ của hệ thống bằng thanh progress bar.

Tạo progress bar resource

Tạo progress bar

Tìm Progress Control trong Toolbox và vẽ 3 progress control với ID lần lượt là: IDC_PROGRESS_HOUR, IDC_PROGRESS_MINUTE, IDC_PROGRESS_SECOND

Tiếp theo, chúng ta tạo 3 biến control cho 3 progressbar lần lượt là: m_ProgressHours, m_ProgressMinutes, m_ProgressSeconds
Click chuột phải vào thanh progress bar, chọn Add Variable…

Tương tự, các bạn add thêm biến m_ProgressMinutes và m_ProgressSeconds. 3 biến này sẽ được tự động add vào source code
File: MFCAppDlg.h

class CMFCAppDlg : public CDialogEx
{
    ...
private:
    CProgressCtrl m_ProgressHours;
    CProgressCtrl m_ProgressMinutes;
    CProgressCtrl m_ProgressSeconds;
};  

File: MFCAppDlg.cpp

void CMFCAppDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_PROGRESS_HOUR, m_ProgressHours);
    DDX_Control(pDX, IDC_PROGRESS_MINUTE, m_ProgressMinutes);
    DDX_Control(pDX, IDC_PROGRESS_SECOND, m_ProgressSeconds);
}

Khởi tạo progress bar

BOOL CMFCAppDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    ...
    m_ProgressHours.SetRange(0, 23);
    m_ProgressHours.SetStep(1);
    m_ProgressMinutes.SetRange(0, 59);
    m_ProgressMinutes.SetStep(1);
    m_ProgressSeconds.SetRange(0, 59);
    m_ProgressSeconds.SetStep(1);

    SetTimer(1, 40, NULL);
    return TRUE;  // return TRUE  unless you set the focus to a control

Sử dụng hàm SetRange(0, 23) và SetStep(1) khởi tạo cho progress giờ từ 0 đến 23, độ phân giải là 1. Hiểu 1 cách đơn giản thì progress bar chia làm 24 độ chia tương ứng với 24 giờ. Tương tự SetRange(0, 59) được dùng để khởi tạo cho
progress phút và giây là 60 độ chia tương ứng với 60 phút và 60 s.

Tạo static text

Tạo 3 static text với nội dung text và ID và assign biến cho static text như sau:

Text ID Variable
HH IDC_VAL_HOUR m_ValueHours
MM IDC_VAL_MINUTE m_ValueMinutes
SS IDC_VAL_SECOND m_ValueSeconds

Để assign biến kiểu value cho static text, chúng ta làm như sau

Chuột phải vào static text “HH”, chọn Add Variable…

Xử lí timer

Để ứng dụng có thể tự động hiển thị sự thay đổi tiến trình, chúng ta cần sử dụng bộ định thời (timer). Để timer hoạt động, chúng ta cần khởi tạo time-out cho timer (ví dụ: 10s). Sau 10s, application nhận được message VM_TIMER từ OS. Khi nhận được message này, chúng ta tiến hành update progress.

Khởi tạo time-out

BOOL CMFCAppDlg::OnInitDialog()
{
    ...
    SetTimer(1, 40, NULL);
    return TRUE;  // return TRUE  unless you set the focus to a control

– Đối số thứ nhất “1” truyền vào hàm SetTimer là ID của timer. (Chú ý: nếu khai báo nhiều timer, ID này khác nhau)
– Đối số thứ hai “40” là giá trị time-out (đơn vị mili giây (ms)).
– Đối số thứ ba NULL là con trỏ trỏ tới hàm handler khi time-out. Ở đây là NULL nghĩa là hệ thống gửi message WM_TIMER tới application.

Xử lí time-out

Sau 40ms time-out, OS gửi message WM_TIMER tới application. Chúng ta cần add thêm handler xử lí message WM_TIMER bằng cách:
Chọn Project -> Class Wizard…

Search message WM_TIMER, click [Add Hanlder], [Apply]. Sau đó, hàm void CMFCAppDlg::OnTimer(UINT_PTR nIDEvent) được add vào file MFCAppDlg.cpp

Chúng ta add thêm source code để lấy giờ trên máy tính, thực hiện update progress, hiển thị thời gian trên static text

void CMFCAppDlg::OnTimer(UINT_PTR nIDEvent)
{
    // Get the current time of the computer
    CTime CurTime = CTime::GetCurrentTime();
    // Find the hour, the minute, and the second values of the time
    int ValHours = CurTime.GetHour();
    int ValMinutes = CurTime.GetMinute();
    int ValSeconds = CurTime.GetSecond();
    // Change each progress bar accordingly
    m_ProgressHours.SetPos(ValHours);
    m_ProgressMinutes.SetPos(ValMinutes);
    m_ProgressSeconds.SetPos(ValSeconds);
    // Display the position of the progress in the right label
    m_ValueHours.Format(L"%d", m_ProgressHours.GetPos());
    m_ValueMinutes.Format(L"%d", m_ProgressMinutes.GetPos());
    m_ValueSeconds.Format(L"%d", m_ProgressSeconds.GetPos());
    UpdateData(FALSE);

    CDialogEx::OnTimer(nIDEvent);
}

Source code

Download

Demo

Be the first to comment

Leave a Reply