⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outbarctrl.cpp

📁 局域网ICQ的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   copyright            : (C) 2002 by Zhang Yong                         *
 *   email                : z-yong163@163.com                              *
 ***************************************************************************/

// OutBarCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "myicq.h"
#include "OutBarCtrl.h"
#include "OutBarEdit.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

OutBarFolder::~OutBarFolder()
{
	for (int i = items.size() - 1; i >= 0; i--)
		delete items[i];
}

void OutBarFolder::addItem(const char *t, int img)
{
	OutBarItem *item = new OutBarItem(t, img);
	items.push_back(item);
}

#define IDT_SCROLL		1001
#define IDT_DBLCLK		1002

/////////////////////////////////////////////////////////////////////////////
// OutBarCtrl

OutBarCtrl::OutBarCtrl()
{
	listener = NULL;
	largeIcons = smallIcons = NULL;
	selFolder = 0;
	bgColor = RGB(128, 128, 192);
	fontColor = RGB(0, 0, 0);
	lastHit =
	pressedHit =
	clickedItem = -1;
	dragItem = -1;
	largeIconView = TRUE;

	editCtrl = NULL;

	currentCursor = NULL;
	handCursor = AfxGetApp()->LoadCursor(IDC_HAND);
	forbiddenCursor = AfxGetApp()->LoadCursor(IDC_FORBIDDEN);
	dragCursor = AfxGetApp()->LoadCursor(IDC_DRAG);
}

OutBarCtrl::~OutBarCtrl()
{
	if (editCtrl)
		delete editCtrl;

	removeAllFolders();
}

int OutBarCtrl::addFolder(const char *text)
{
	OutBarFolder *f = new OutBarFolder(text);
	folders.push_back(f);
	return folders.size() - 1;
}

void OutBarCtrl::addItem(int folder, const char *text, int image)
{
	if (folder >= 0 && folder < getFolderCount())
		folders[folder]->addItem(text, image);
}

void OutBarCtrl::insertItem(int folder, int pos, OutBarItem *item)
{
	if (folder >= 0 && folder < getFolderCount()) {
		vector<OutBarItem *> &items = folders[folder]->items;
		items.insert(items.begin() + pos, item);
	}
}

void OutBarCtrl::getFolderName(int i, CString &name)
{
	if (i >= 0 && i < getFolderCount())
		name = folders[i]->text;
}

int OutBarCtrl::getItemCount(int folder)
{
	return folders[folder]->items.size();
}

int &OutBarCtrl::scrollPos()
{
	return folders[selFolder]->scrollPos;
}

int OutBarCtrl::getCountPerPage()
{
	CRect rc;
	getInsideRect(rc);

	int h = (largeIconView ? LARGE_ITEM_H : SMALL_ITEM_H);
	return ((rc.Height() / h) + 1);
}

void OutBarCtrl::setSelFolder(int i)
{
	if (i != selFolder && i < getFolderCount())
		selFolder = i;
}

void OutBarCtrl::getFolderRect(CRect &rc, int i)
{
	GetClientRect(rc);
	
	if (i <= selFolder)
		rc.top += i * FOLDER_HEIGHT;
	else
		rc.top = rc.bottom - (folders.size() - i) * FOLDER_HEIGHT;
		
	rc.bottom = rc.top + FOLDER_HEIGHT;
}

void OutBarCtrl::getInsideRect(CRect &rc)
{
	GetClientRect(rc);
	rc.top += (selFolder + 1) * FOLDER_HEIGHT;
	rc.bottom -= (folders.size() - selFolder - 1) * FOLDER_HEIGHT;
}

void OutBarCtrl::getItemRect(CRect &rc, int i)
{
	getInsideRect(rc);
	
	int h = (largeIconView ? LARGE_ITEM_H : SMALL_ITEM_H);
	rc.top += h * (i - scrollPos()) + ICON_OFFSET;	
	rc.bottom = rc.top + h;
}

void OutBarCtrl::getIconRect(CRect &rc, int i)
{
	getItemRect(rc, i);
	
	if (largeIconView) {
		rc.left += (rc.Width() - LARGE_ICON_W) / 2;
		rc.right = rc.left + LARGE_ICON_W;
		rc.bottom = rc.top + LARGE_ICON_H;
	} else {
		rc.top += (rc.Height() - SMALL_ICON_H) / 2;
		rc.bottom = rc.top + SMALL_ICON_H;
		rc.left += 2;
		rc.right = rc.left + SMALL_ICON_W;
	}
}

void OutBarCtrl::getLabelRect(CRect &rc, int i)
{
	getItemRect(rc, i);
	
	if (largeIconView)
		rc.top += LARGE_ICON_H;
	else
		rc.left += SMALL_ICON_W + 2 + 5;
}

void OutBarCtrl::getScrollRect(CRect &rc, int i)
{
	getInsideRect(rc);
	int size = GetSystemMetrics(SM_CXVSCROLL);

	rc.right -= 5;
	rc.left = rc.right - size;

	if (i == SCROLL_DIR_UP) {
		rc.top += 5;
		rc.bottom = rc.top + size;
	} else {
		rc.bottom -= 5;
		rc.top = rc.bottom - size;
	}
}

void OutBarCtrl::repaintInsideRect()
{
	CRect rc;
	getInsideRect(rc);
	InvalidateRect(rc);
}

HIT OutBarCtrl::hitTest(const CPoint &pt)
{
	int obj = HT_NONE;
	int index = -1;
	CRect rcClient, rc;
	GetClientRect(rcClient);
	getInsideRect(rc);

	if (!rc.PtInRect(pt)) {
		if (pt.y >= 0 && pt.y < rc.top) {
			obj = HT_FOLDER;
			index = (pt.y - 1) / FOLDER_HEIGHT;
		} else if (pt.y > rc.bottom && pt.y < rcClient.bottom - 1) {
			obj = HT_FOLDER;
			index = (pt.y - rc.bottom) / FOLDER_HEIGHT + selFolder + 1;
		}
	} else {
		for (int i = 0; i < 2; i++) {
			if (canScroll(i)) {
				CRect rcScroll;
				getScrollRect(rcScroll, i);
				if (rcScroll.PtInRect(pt))
					return MAKEHIT(HT_SCROLL, i);
			}
		}
	
		if (largeIconView) {
			int offset = (rc.Width() - LARGE_ICON_W) / 2;
			if (pt.x >= rc.left + offset &&
				pt.x <= rc.right - offset) {
				int y = pt.y - rc.top;
				offset = y % LARGE_ITEM_H - ICON_OFFSET;
				if (offset >= 0 && offset <= LARGE_ICON_H) {
					int i = y / LARGE_ITEM_H + scrollPos();
					if (i <= getMaxVisibleItem()) {
						obj = HT_ITEM;
						index = i;
					}
				}
			}
		} else if (pt.x < SMALL_ICON_W + 32) {
			int i = (pt.y - rc.top) / SMALL_ITEM_H + scrollPos();
			if (i <= getMaxVisibleItem()) {
				obj = HT_ITEM;
				index = i;
			}
		}
	}
	
	return MAKEHIT(obj, index);
}

BOOL OutBarCtrl::canScroll(int dir)
{
	if (dir == SCROLL_DIR_UP)
		return (scrollPos() > 0);

	int n = getCountPerPage();
	return (n + scrollPos() <= getItemCount());
}

void OutBarCtrl::scroll(int dir, int delta)
{
	if (dir == SCROLL_DIR_UP)
		scrollPos() -= delta;
	else
		scrollPos() += delta;

	if (!canScroll(dir)) {
		KillTimer(IDT_SCROLL);
			
		CClientDC dc(this);
		drawScroll(&dc, dir);
		pressedHit = lastHit = HITNONE;
	}
		
	repaintInsideRect();
}

void OutBarCtrl::drawFolder(CDC *pDC, int i, BOOL pressed, BOOL hilight)
{
	CRect rc;
	getFolderRect(rc, i);

	if (pressed) {
		pDC->Draw3dRect(rc, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_BTNHILIGHT));
		rc.InflateRect(-1, -1);
		pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNFACE));
	} else if (hilight) {
		pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
		rc.InflateRect(-1, -1);
		pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_3DDKSHADOW));
	} else
		pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));

	rc.InflateRect(-1, -1);
	pDC->FillSolidRect(rc, GetSysColor(COLOR_BTNFACE));
	
	if (pressed)
		rc.OffsetRect(1, 1);

	drawFolderText(pDC, i, rc);
}

void OutBarCtrl::drawFolderText(CDC *pDC, int i, CRect &rc)
{
	CFont *oldFont = pDC->SelectObject(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
	int oldBkMode = pDC->SetBkMode(TRANSPARENT);

	pDC->DrawText(folders[i]->text, rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

	pDC->SetBkMode(oldBkMode);
	pDC->SelectObject(oldFont);
}

void OutBarCtrl::drawItem(CDC *pDC, int i, BOOL redraw)
{
	CRect rc;
	getIconRect(rc, i);
	if (redraw) {
		CRect clip;
		getInsideRect(clip);
		CRgn rgn;
		rgn.CreateRectRgnIndirect(clip);
		pDC->SelectClipRgn(&rgn);
		drawBackground(pDC, rc);
	}
	drawItemImage(pDC, i, rc);
	if (!redraw)
		drawItemText(pDC, i, fontColor);
}

int OutBarCtrl::getMaxVisibleItem()
{
	int max = getCountPerPage() + scrollPos();
	if (max > getItemCount())
		max = getItemCount();
	return (--max);
}

void OutBarCtrl::drawBackground(CDC *pDC, CRect &rc)
{
	pDC->FillSolidRect(rc, bgColor);
}

void OutBarCtrl::drawItemImage(CDC *pDC, int i, CRect &rc)
{
	int img = folders[selFolder]->items[i]->image;
	CImageList *imageList = (largeIconView ? largeIcons : smallIcons);
	imageList->Draw(pDC, img, rc.TopLeft(), ILD_TRANSPARENT);
}

void OutBarCtrl::drawItemText(CDC *pDC, int i, COLORREF color)
{
	CRect rc;
	getLabelRect(rc, i);
	OutBarItem *item = folders[selFolder]->items[i];
	int style = DT_SINGLELINE | DT_VCENTER;
	if (largeIconView)
		style |= DT_CENTER;

	CFont *oldFont = pDC->SelectObject(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
	COLORREF oldColor = pDC->SetTextColor(color);
	int oldBkMode = pDC->SetBkMode(TRANSPARENT);

	pDC->DrawText(item->text, rc, style);

	pDC->SetBkMode(oldBkMode);
	pDC->SetTextColor(oldColor);
	pDC->SelectObject(oldFont);
}

void OutBarCtrl::hilightItem(CDC *pDC, int i, BOOL pressed)
{	
	CRect rc;
	getInsideRect(rc);
	CRgn rgn;
	rgn.CreateRectRgnIndirect(rc);
	pDC->SelectClipRgn(&rgn);
	getIconRect(rc, i);
	
	if (pressed)
		pDC->Draw3dRect(rc, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_BTNHILIGHT));
	else
		pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
}

void OutBarCtrl::drawScroll(CDC *pDC, int i, BOOL pressed)
{
	CRect rc;
	getScrollRect(rc, i);

	int state = (i == SCROLL_DIR_UP ? DFCS_SCROLLUP : DFCS_SCROLLDOWN);
	if (pressed)
		state |= DFCS_PUSHED;
	pDC->DrawFrameControl(rc, DFC_SCROLL, state);
}

void OutBarCtrl::removeFolder(int i)
{
	delete folders[i];
	folders.erase(folders.begin() + i);
	Invalidate();
}

void OutBarCtrl::removeAllFolders()
{
	for (int i = folders.size() - 1; i >= 0; i--)
		delete folders[i];
	folders.clear();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -