www.gusucode.com > 类似Windows拷贝文件一样的进度条VC实现-源码程序 > 类似Windows拷贝文件一样的进度条VC实现-源码程序/code/IconProgress.cpp
// IconProgress.cpp : implementation file // Download by http://www.NewXing.com #include "stdafx.h" #include "IconProgressApp.h" #include "IconProgress.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // Constants const int CIconProgress::HORIZONTAL = 0; const int CIconProgress::VERTICAL = 1; // Message map BEGIN_MESSAGE_MAP(CIconProgress, CWnd) //{{AFX_MSG_MAP(CIconProgress) ON_WM_PAINT() ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Constructor CIconProgress::CIconProgress() { upper = 100; lower = 0; position = 0; step = 10; } ///////////////////////////////////////////////////////////////////////////// // Destructor CIconProgress::~CIconProgress() { background_brush.DeleteObject(); } ///////////////////////////////////////////////////////////////////////////// // SetInitial - default colour void CIconProgress::Attach(UINT control_id, CWnd *parent, UINT icon_id, int increment, int stagger) { Attach(control_id, parent, icon_id, increment, GetSysColor(COLOR_3DFACE), stagger); } ///////////////////////////////////////////////////////////////////////////// // SetInitial - specified colour void CIconProgress::Attach(UINT control_id, CWnd *parent, UINT icon_id, int increment, COLORREF background, int stagger) { SubclassDlgItem(control_id, parent); // Store the parameters. icon_increment = increment; background_colour = background; stagger_distance = stagger; // Create the background brush. background_brush.CreateSolidBrush(background_colour); // Get the icon handle. hicon = AfxGetApp()->LoadIcon(icon_id); // Find the client window size. GetClientRect(&window_rect); // Set the orientation and the major and minor axis. // Major is in the direction of progress. if (window_rect.right > window_rect.bottom) { orientation = HORIZONTAL; } else { orientation = VERTICAL; } switch (orientation) { case HORIZONTAL: { icon_major = GetSystemMetrics(SM_CXICON); icon_minor = GetSystemMetrics(SM_CYICON); window_minor = window_rect.bottom; window_major = window_rect.right; break; } case VERTICAL: { icon_minor = GetSystemMetrics(SM_CXICON); icon_major = GetSystemMetrics(SM_CYICON); window_major = window_rect.bottom; window_minor = window_rect.right; break; } } // Adjust for daft icon increment. if (icon_increment == 0) { icon_increment = 1; } // Find the number of icons that will fit in the window. total_number_of_icons = 1; while (((total_number_of_icons * icon_increment) + icon_major) < window_major) { total_number_of_icons++; } // Fill the icon array with the default icon hicon_array.SetSize(total_number_of_icons); for (int i = 0; i < total_number_of_icons; i++) { hicon_array[i] = hicon; } // Find the start points. switch (orientation) { case HORIZONTAL: { // Left. start_major = (window_major - (((total_number_of_icons - 1) * icon_increment) + icon_major)) / 2; break; } case VERTICAL: { // Bottom. start_major = ((window_major + (((total_number_of_icons - 1) * icon_increment) + icon_major)) / 2) - icon_major; } } start_minor = (window_minor - icon_minor - stagger_distance) / 2; } ///////////////////////////////////////////////////////////////////////////// // SetPos int CIconProgress::SetPos(int new_position) { int old_position; old_position = position; position = new_position; position = min(upper, max(lower, position)); number_of_icons = GetNumberOfIcons(position); Invalidate(); return old_position; } ///////////////////////////////////////////////////////////////////////////// // OffsetPos int CIconProgress::OffsetPos(int offset) { int old_position; old_position = position; position += offset; position = min(upper, max(lower, position)); number_of_icons = GetNumberOfIcons(position); Invalidate(); return old_position; } ///////////////////////////////////////////////////////////////////////////// // SetRange void CIconProgress::SetRange(short lower_range, short upper_range) { SetRange32(lower_range, upper_range); } ///////////////////////////////////////////////////////////////////////////// // SetRange32 void CIconProgress::SetRange32(int lower_range, int upper_range) { lower = lower_range; upper = upper_range; position = min(upper, max(lower, position)); number_of_icons = GetNumberOfIcons(position); Invalidate(); } ///////////////////////////////////////////////////////////////////////////// // SetIconChange void CIconProgress::SetIconChange(UINT icon_id, int position) { HICON hicon = AfxGetApp()->LoadIcon(icon_id); // Where to start from int change_icon_index = GetNumberOfIcons(position); // Fill part of the array with the new icon for (int i = change_icon_index; i < total_number_of_icons; i++) { hicon_array[i] = hicon; } } ///////////////////////////////////////////////////////////////////////////// // SetStep int CIconProgress::SetStep(int new_step) { int old_step; old_step = step; step = new_step; return old_step; } ///////////////////////////////////////////////////////////////////////////// // StepIt int CIconProgress::StepIt() { int old_position; old_position = position; position += step; position = min(upper, max(lower, position)); number_of_icons = GetNumberOfIcons(position); Invalidate(); return old_position; } ///////////////////////////////////////////////////////////////////////////// // GetPos int CIconProgress::GetPos() { return position; } ///////////////////////////////////////////////////////////////////////////// // GetRange void CIconProgress::GetRange(int &lower_range, int &upper_range) { lower_range = lower; upper_range = upper; } ///////////////////////////////////////////////////////////////////////////// // GetNumberOfIcons int CIconProgress::GetNumberOfIcons(int position) { int n_icons; float delta = (float)(position - lower); float range = (float)(upper - lower + 1); float range_per_icon = range / total_number_of_icons; // Just in case of rounding errors if (position == upper) { n_icons = total_number_of_icons; } else { n_icons = (int)(delta / range_per_icon); } return n_icons; } ///////////////////////////////////////////////////////////////////////////// // CIconProgress message handlers void CIconProgress::OnPaint() { CPaintDC dc(this); CDC memdc; CBitmap bitmap; int x, y, count; BOOL do_stagger = FALSE; // Create a memory copy to draw to. memdc.CreateCompatibleDC(&dc); bitmap.CreateCompatibleBitmap(&dc, window_rect.right, window_rect.bottom); memdc.SelectObject(&bitmap); // Clear the background. memdc.FillRect(&window_rect, &background_brush); // Draw the icons. switch (orientation) { case HORIZONTAL: { for (x = start_major, count = 0; count < number_of_icons; x += icon_increment, count++) { if (do_stagger) { memdc.DrawIcon(x, start_minor + stagger_distance, hicon_array[count]); } else { memdc.DrawIcon(x, start_minor, hicon_array[count]); } do_stagger = !do_stagger; } break; } case VERTICAL: { for (y = start_major, count = 0; count < number_of_icons; y -= icon_increment, count++) { if (do_stagger) { memdc.DrawIcon(start_minor + stagger_distance, y, hicon_array[count]); } else { memdc.DrawIcon(start_minor, y, hicon_array[count]); } do_stagger = !do_stagger; } break; } } // Copy it to the screen. dc.BitBlt(0, 0, window_rect.right, window_rect.bottom, &memdc, 0, 0, SRCCOPY); // Delete the tempory resources. memdc.DeleteDC(); bitmap.DeleteObject(); } BOOL CIconProgress::OnEraseBkgnd(CDC* pDC) { // Indicate that it is already erased. return TRUE; }