windows-nt/Source/XPSP1/NT/shell/osshell/cpls/usb/fuelbar.cpp
2020-09-26 16:20:57 +08:00

385 lines
9.6 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1993-1995
* TITLE: FUELBAR.CPP
* VERSION: 1.0
* AUTHOR: jsenior
* DATE: 10/28/1998
*
********************************************************************************
*
* CHANGE LOG:
*
* DATE REV DESCRIPTION
* ---------- ------- ----------------------------------------------------------
* 10/28/1998 jsenior Original implementation.
*
*******************************************************************************/
#include "FuelBar.h"
#include "debug.h"
#include <assert.h>
const int FuelBar::NoImage = -1;
const LPVOID FuelBar::NoID = (const LPVOID) -1;
FuelBar::FuelBar() : currentTotalValue(0), highlightID(NoID),
maxValue(100), calcRects(FALSE), hImageList(0)
{
GetSysColors();
}
FuelBar::~FuelBar()
{
Clear();
}
BOOL FuelBar::SubclassDlgItem( UINT nID, HWND hParent)
{
hwnd = GetDlgItem(hParent, nID);
FuelSetWindowLongPtr(hwnd, FUELGWLP_USERDATA, (FUELLONG_PTR) this);
prevWndProc = (WNDPROC) FuelSetWindowLongPtr(hwnd,
FUELGWLP_WNDPROC,
(FUELDWORD_PTR) StaticWndProc);
return TRUE;
}
UINT FuelBar::AddItem(UINT Value, LPVOID ID, int ImageIndex)
{
FuelBarItem item;
if (!Value)
return 0;
if (currentTotalValue + Value > maxValue)
return 0;
currentTotalValue += Value;
item.value = Value;
item.id = ID;
item.imageIndex = ImageIndex;
items.push_back(item);
calcRects = TRUE;
return currentTotalValue;
}
BOOL FuelBar::RemoveItem(LPVOID ID)
{
if (highlightID == ID) {
highlightID = (LPVOID) NoID;
}
FuelBarItem *item;
for (item = items.begin(); item; item = items.next()) {
if (item->id == ID) {
items.eraseCurrent();
return TRUE;
}
}
return FALSE;
}
void FuelBar::ClearItems()
{
Clear();
InvalidateRect(hwnd, NULL, TRUE);
}
BOOL FuelBar::HighlightItem(LPVOID ID)
{
// do nothing if the id is the same
if (ID == highlightID)
return TRUE;
FuelBarItem *item;
highlightID = 0;
//
// Make sure that ID is indeed a member
//
for (item = items.begin(); item; item = items.next()) {
if (item->id == ID) {
highlightID = ID;
break;
}
}
// the total redrawing of the ctrl will erase the old and draw the new
InvalidateRect(hwnd, NULL, FALSE);
if (ID != highlightID) {
return FALSE;
}
return TRUE;
}
void FuelBar::Clear()
{
items.clear();
currentTotalValue = 0;
calcRects = TRUE;
}
void FuelBar::CalculateRects(const RECT& ClientRect)
{
FuelBarItem *item, *prevItem;
if (items.empty()) {
calcRects = FALSE;
return;
}
item = items.begin();
item->rect = ClientRect;
item->rect.right = ClientRect.left + 1 +
(item->value * (ClientRect.right - ClientRect.left))/maxValue;
prevItem = item;
for (item = items.next(); item; item = items.next()) {
item->rect.top = prevItem->rect.top;
item->rect.bottom = prevItem->rect.bottom;
item->rect.left = prevItem->rect.right;
// Fill rect does not render the outside edge
item->rect.right = item->rect.left + 1 +
(item->value * (ClientRect.right - ClientRect.left))/maxValue;
prevItem = item;
}
// make sure that if the bar is full, that the last item is rendered to
// the edge of the entire bar
if (currentTotalValue == maxValue)
item->rect.right = ClientRect.right;
calcRects = FALSE;
}
void FuelBar::SetImageList(HIMAGELIST ImageList)
{
IMAGEINFO imageInfo;
hImageList = ImageList;
ZeroMemory(&imageInfo, sizeof(IMAGEINFO));
if (ImageList_GetImageInfo(hImageList, 0, &imageInfo)) {
imageWidth = imageInfo.rcImage.right - imageInfo.rcImage.left;
imageHeight = imageInfo.rcImage.bottom - imageInfo.rcImage.top;
}
else {
assert(FALSE);
}
}
void FuelBar::GetSysColors()
{
colorFace = GetSysColor(COLOR_3DFACE);
colorLight = GetSysColor(COLOR_3DHILIGHT);
colorDark = GetSysColor(COLOR_3DSHADOW);
colorUnused = GetSysColor(COLOR_WINDOW);
}
/////////////////////////////////////////////////////////////////////////////
// FuelBar message handlers
void FillSolidRect(HDC dc,
LPCRECT rect,
COLORREF color)
{
SetBkColor(dc, color);
ExtTextOut(dc, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
}
void FillSolidRect(HDC dc, int x, int y, int cx, int cy, COLORREF color)
{
RECT rect;
rect.left = x;
rect.right = x + cx;
rect.top = y;
rect.bottom = y + cy;
SetBkColor(dc, color);
ExtTextOut(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
}
void Draw3dRect(HDC dc,
int x,
int y,
int cx,
int cy,
COLORREF clrTopLeft,
COLORREF clrBottomRight,
COLORREF clrFace)
{
FillSolidRect(dc, x, y, cx - 1, 1, clrTopLeft);
FillSolidRect(dc, x, y, 1, cy - 1, clrTopLeft);
FillSolidRect(dc, x + cx, y, -1, cy, clrBottomRight);
FillSolidRect(dc, x, y + cy, cx, -1, clrBottomRight);
FillSolidRect(dc, x+1, y+1, cx-2, cy-2, clrFace) ;
}
void FuelBar::OnPaint()
{
HDC dc;
PAINTSTRUCT ps;
RECT clientRect, *highlightRect, remainingRect;
POINT pt;
FuelBarItem *item, *prevItem;
HBRUSH hBrush, hOldBrush;
BOOL highlightFound = FALSE;
dc = BeginPaint(hwnd, &ps);
hBrush = CreateSolidBrush(colorFace);
hOldBrush = (HBRUSH) SelectObject(dc, hBrush);
GetClientRect(hwnd, &clientRect);
FillSolidRect(dc, &clientRect, colorUnused);
if (calcRects) {
CalculateRects(clientRect);
// FillSolidRect(dc, &clientRect, colorFace);
}
for (item = items.begin(); item; item = items.next()) {
Draw3dRect(dc,
item->rect.left,
item->rect.top,
item->rect.right - item->rect.left,
item->rect.bottom - item->rect.top,
colorLight,
colorDark,
colorFace);
if (item->imageIndex != NoImage &&
(item->rect.right - item->rect.left) > imageWidth) {
// render the image in the center of the rectangle
pt.x = item->rect.left +
(item->rect.right - item->rect.left)/2 - (imageWidth)/2;
pt.y = (item->rect.bottom - item->rect.top)/2 - (imageHeight)/2;
ImageList_Draw(hImageList,
item->imageIndex,
dc,
pt.x,
pt.y,
ILD_TRANSPARENT);
}
if (item->id == highlightID) {
highlightRect = &item->rect;
highlightFound = TRUE;
}
prevItem = item;
}
if (currentTotalValue < maxValue) {
remainingRect = clientRect;
if (!items.empty())
remainingRect.left = prevItem->rect.right;
FillSolidRect(dc, &remainingRect, colorUnused);
}
SelectObject(dc, hOldBrush);
if (highlightFound) {
// CPen pen(PS_SOLID, 1, RGB(0,0,0)), *oldPen;
// oldPen = dc.SelectObject(&pen);
HPEN hPen, hOldPen;
hPen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
if (hPen) {
hOldPen = (HPEN) SelectObject(dc, hPen);
MoveToEx(dc, highlightRect->left, highlightRect->top, NULL);
LineTo(dc, highlightRect->right-1, highlightRect->top);
LineTo(dc, highlightRect->right-1, highlightRect->bottom-1);
LineTo(dc, highlightRect->left, highlightRect->bottom-1);
LineTo(dc, highlightRect->left, highlightRect->top);
// dc.DrawFocusRect instead?
SelectObject(dc, hOldPen);
DeleteObject(hPen);
}
}
EndPaint(hwnd, &ps);
DeleteObject(hBrush);
ValidateRect(hwnd, &clientRect);
}
BOOL FuelBar::OnToolTipNotify(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
{
BOOL bHandledNotify = FALSE;
#ifdef TOOL
CPoint cursorPos;
CRect clientRect;
VERIFY(::GetCursorPos(&cursorPos));
ScreenToClient(&cursorPos);
GetClientRect(clientRect);
// Make certain that the cursor is in the client rect, because the
// mainframe also wants these messages to provide tooltips for the
// toolbar.
if (clientRect.PtInRect(cursorPos)) {
FuelItem* item;
int i;
for (i = 0; i < items.GetSize(); i++) {
item = (FuelItem*) items[i];
}
bHandledNotify = TRUE;
}
#endif
return bHandledNotify;
}
void FuelBar::OnSysColorChange()
{
GetSysColors();
}
BOOL APIENTRY FuelBar::StaticWndProc(IN HWND hDlg,
IN UINT uMessage,
IN WPARAM wParam,
IN LPARAM lParam)
{
FuelBar *that = (FuelBar*) FuelGetWindowLongPtr(hDlg, FUELGWLP_USERDATA);
assert(that);
switch (uMessage) {
case WM_PAINT:
that->OnPaint();
break;
}
return (BOOL)CallWindowProc( (FUELPROC) that->prevWndProc,
hDlg,
uMessage,
wParam,
lParam);
}
LPVOID FuelBar::GetHighlightedItem()
{
return highlightID;
}