📄 iconprogress.cpp
字号:
// IconProgress.cpp : implementation file
//
#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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -