Как избавиться от 16-ти цветов в панели инструментов ?
В главном окне любого современного профессионально написанного приложения имеется как минимум два дополнительных инструмента, значительно облегчающих работу, - это панель инструментов (Toolbar) и строка состояния (Statusbar). Но нас интересует только первое панель инструментов. С появлением Microsoft Windows 95\98 большинство приложений использовали 16-ти цветные битмапы в панелях инструментов, но с приходом Microsoft Windows 2000\XP всё изменилось и приложения стали использовать 256 и больше цветов в битмапах. Ну, а мы чем хуже !
Но есть небольшая проблема, редактор панелей инструментов в Visual Studio не поддерживает больше 16 цветов :( ! Так что придётся всё делать ручками ! Битмап с изображением панели инструментов придётся рисовать самому в каком-нибудь графическом редакторе, например в Adobe Photoshop. Да, фон этого битмапа должен быть следующего цвета : RGB (192,192,192). Панель инструментов придётся прописывать в ручную в файле ресурсов (*.rc), например :
IDR_MAINFRAME TOOLBAR 16,16 BEGIN BUTTON ID_FILE_NEW BUTTON ID_FILE_OPEN BUTTON ID_FILE_SAVE SEPARATOR BUTTON ID_EDIT_CUT BUTTON ID_EDIT_COPY BUTTON ID_EDIT_PASTE SEPARATOR BUTTON ID_FILE_PRINT BUTTON ID_APP_ABOUT END
После загрузки панели инструментов функцией CToolBar::LoadToolBar, Вам придётся загрузить в ручную битмап панели инструментов с помощью LoadImage образом :
HBITMAP hBitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP,
0, 0,LR_CREATEDIBSECTION|LR_LOADMAP3DCOLORS);
После создать два обьекта CBitmap и присоединить к ним hBitmap :
CBitmap BitmapNormal;
CBitmap BitmapDisabled;
if (!BitmapNormal.Attach(hBitmap))
{
TRACE("Can't attach BitmapNormal !\n");
return false;
}
if (!BitmapDisabled.Attach(hBitmap))
{
TRACE("Can't attach BitmapDisabled !\n");
return false;
}
А зачем BitmapDisabled спросите Вы ?
Кнопки панели инструментов иногда бывают заблокированы, например когда у кнопки нет обработчика, нет конечно можно самому нарисовать Disabled Bitmap, но согласитесь тратить время когда все можно сделать программно. Да, но перед тем как что-то делать, с этими битмапами необходимо заменить их фон RGB(192.192.192) на фон который можно получить с помощью функции ::GetSysColor(COLOR_BTNFACE). Далее создать два объекта типа CImageList, добавим с помощью функции int Add(CBitmap* pbmImage, CBitmap* pbmMask) наши битмапы (BitmapNormal и BitmapDisabled), причём вторым параметром будем передавать reinterpret_cast<CBitmap*>(NULL). Для того чтобы закончить нашу работу по созданию панели инструментов нам необходимо добавить наши image list's, созданные выше, к панели инструментов. Для того чтобы добавить эти необходимо воспользоваться функцией GetToolBarCtrl() которая вернёт ссылку на объект класса CToolBarCtrl. У данного класса (CToolBarCtrl) есть две функции:
CImageList* SetImageList(CImageList* pImageList); CImageList* SetDisabledImageList(CImageList* pImageList); Вот ими-то мы и воспользуемся : GetToolBarCtrl().SetImageList(&m_NormalImageList); GetToolBarCtrl().SetDisabledImageList(&m_DisabledImageList);
Всё наша панель инструментов готова !
Ну и в завершении данной стать я приведу полный текст класса которой в краткой форме описал выше :
AdvToolBar.h
#pragma once
// CAdvToolBar
#ifndef ADVTOOLBAR_H
#define ADVTOOLBAR_H
class CAdvToolBar : public CToolBar
{
DECLARE_DYNAMIC(CAdvToolBar)
public:
enum
{
ADVT_COLOR_256=0,
ADVT_COLOR_TRUE
};
CAdvToolBar();
virtual~CAdvToolBar();
// Создаёт панель инструментов и присоединяет к ней необходимые ресурсы
bool CreateAdvToolBar(CWnd* pParentWnd,UINT nIDResource,
const int nColorType=CAdvToolBar::ADVT_COLOR_256,
DWORD dwCtrlStyle = TBSTYLE_FLAT,DWORD dwStyle = WS_CHILD |
WS_VISIBLE | CBRS_ALIGN_TOP);
CImageList* GetNormalImageList()
{
return reinterpret_cast<CImageList*>(&m_NormalImageList);
}
CImageList* DisabledImageList()
{
return reinterpret_cast<CImageList*>(&m_DisabledImageList);
}
private :
COLORREF LightenColor(COLORREF color,COLORREF color2);
void GetDisabledBitmap(CBitmap &Bitmap);
void ReplaceBackgroundColor(CBitmap& Bitmap);
CImageList m_NormalImageList;
CImageList m_DisabledImageList;
DECLARE_MESSAGE_MAP()
};
#endif //ADVTOOLBAR_H
AdvToolBar.cpp
#include "stdafx.h"
#include "ToolBar.h"
#include "AdvToolBar.h"
#include <AfxPriv.h> //для ASSERT_VALID_IDR
// CAdvToolBar
IMPLEMENT_DYNAMIC(CAdvToolBar, CToolBar)
CAdvToolBar::CAdvToolBar()
{}
CAdvToolBar::~CAdvToolBar()
{}
BEGIN_MESSAGE_MAP(CAdvToolBar, CToolBar)
END_MESSAGE_MAP()
bool CAdvToolBar::CreateAdvToolBar(CWnd* pParentWnd,
UINT nIDResource,
const int nColorType/*=CAdvToolBar::ADVT_COLOR_256*/,
DWORD dwCtrlStyle/* = TBSTYLE_FLAT*/,
DWORD dwStyle/* = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP*/)
{
ASSERT(pParentWnd);
ASSERT_VALID_IDR(nIDResource);
if(!CToolBar::CreateEx(pParentWnd,dwCtrlStyle,dwStyle,CRect(0,0,0,0),
nIDResource))
{
TRACE("Can't create tolbar %d !\n",nIDResource);
return false;
}
if(!CToolBar::LoadToolBar(nIDResource))
{
TRACE("Can't load tool bar %d !",nIDResource);
return false;
}
SendMessage(TB_SETEXTENDEDSTYLE,0,TBSTYLE_EX_DRAWDDARROWS);
HBITMAP hBitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(nIDResource),
IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADMAP3DCOLORS);
if(!hBitmap)
{
TRACE("Can't load image tool bar from bitmap !\n");
return false;
}
CBitmap BitmapNormal;
CBitmap BitmapDisabled;
if(!BitmapNormal.Attach(hBitmap))
{
TRACE("Can't attach BitmapNormal !\n");
return false;
}
if(!BitmapDisabled.Attach(hBitmap))
{
TRACE("Can't attach BitmapDisabled !\n");
return false;
}
ReplaceBackgroundColor(BitmapNormal);
ReplaceBackgroundColor(BitmapDisabled);
UINT uImagesListsFlag=0;
switch(nColorType)
{
case 0:
uImagesListsFlag|=ILC_COLOR8;
break;
case 1:
uImagesListsFlag|=ILC_COLOR24;
break;
default:
ASSERT(FALSE);
}
m_NormalImageList.DeleteImageList();
if(!m_NormalImageList.Create(16,16,uImagesListsFlag,0,0))
{
TRACE("Can't create m_NormalImageList !\n");
return false;
}
m_DisabledImageList.DeleteImageList();
if(!m_DisabledImageList.Create(16,16,uImagesListsFlag,0,0))
{
TRACE("Can't create m_DisabledImageList !\n");
return false;
}
m_NormalImageList.Add(&BitmapNormal,reinterpret_cast<CBitmap*>(NULL));
GetToolBarCtrl().SetImageList(&m_NormalImageList);
GetDisabledBitmap(BitmapDisabled);
m_DisabledImageList.Add(&BitmapDisabled,reinterpret_cast<CBitmap*>(NULL));
GetToolBarCtrl().SetDisabledImageList(&m_DisabledImageList);
SetSizes(CSize(23,23),CSize(16,16));
CString strTitle;
if(strTitle.LoadString(nIDResource))
SetWindowText(strTitle);
return true;
}
COLORREF CAdvToolBar::LightenColor(COLORREF color,COLORREF color2)
{
BYTE r=0;
BYTE g=0;
BYTE b=0;
int avgcol=0;
double factor=0;
r = GetRValue(color2);
g = GetGValue(color2);
b = GetBValue(color2);
avgcol = (r+g+b)/3;
factor = avgcol/255.0;
if(factor>0.0 && factor<=1.0)
{
BYTE red,green,blue,lightred,lightgreen,lightblue;
red = GetRValue(color);
green = GetGValue(color);
blue = GetBValue(color);
lightred = (BYTE)((factor*(255-red)) + red);
lightgreen = (BYTE)((factor*(255-green)) + green);
lightblue = (BYTE)((factor*(255-blue)) + blue);
color = RGB(lightred,lightgreen,lightblue);
}
return color;
}
void CAdvToolBar::GetDisabledBitmap(CBitmap& Bitmap)
{
CDC dc;
COLORREF bgcolor,color,disabledcolor;
BITMAP BitMap;
Bitmap.GetBitmap(&BitMap);
dc.CreateCompatibleDC(NULL);
CBitmap * pdcOldBmp = dc.SelectObject(&Bitmap);
CDC dc2;
CBrush brush;
CBitmap Bitmap2;
dc2.CreateCompatibleDC(NULL);
Bitmap2.CreateCompatibleBitmap(&dc,BitMap.bmWidth,BitMap.bmHeight);
color=GetSysColor(COLOR_3DFACE);
brush.CreateSolidBrush(color);
CBitmap * pdcOldBmp2 = dc2.SelectObject(&Bitmap2);
CRect rect(0,0,BitMap.bmWidth,BitMap.bmHeight);
dc2.FillRect(rect,&brush);
bgcolor=dc2.GetPixel(1,1);
brush.DeleteObject();
dc2.SelectObject(pdcOldBmp2);
disabledcolor=GetSysColor(COLOR_BTNSHADOW);
for(int i=0;i<BitMap.bmWidth;i++)
{
for(int j=0;j<BitMap.bmHeight;j++)
{
color=dc.GetPixel(i,j);
if(color!=bgcolor)
{
dc.SetPixel(i,j,LightenColor(disabledcolor,color));
}
}
}
dc.SelectObject(pdcOldBmp);
}
void CAdvToolBar::ReplaceBackgroundColor (CBitmap& Bitmap)
{
CDC dc;
COLORREF bgcolor,color,NormalColor;
bgcolor=RGB(192,192,192);
NormalColor=::GetSysColor(COLOR_BTNFACE);
BITMAP BitMap;
Bitmap.GetBitmap(&BitMap);
dc.CreateCompatibleDC(NULL);
CBitmap * pdcOldBmp = dc.SelectObject(&Bitmap);
for(int i=0;i<BitMap.bmWidth;i++)
{
for(int j=0;j<BitMap.bmHeight;j++)
{
color=dc.GetPixel(i,j);
if(color==bgcolor)
{
dc.SetPixel(i,j,NormalColor);
}
}
}
dc.SelectObject(pdcOldBmp);
}
P.S. Напоследок небольшая программа, демонстрирующая работу данного класса. Загрузить (48 КБ)
Оставить комментарий
Комментарии


