📄 xshadebutton.cpp
字号:
RGBQUAD pal[256];
RGBQUAD* ppal;
BYTE* iDst;
int ni;
ppal=(RGBQUAD*)&pal[0];
iDst = (BYTE*)(hDib) + sizeof(BITMAPINFOHEADER);
for (ni=0;ni<m_nColors;ni++){ pal[ni]=RGB2RGBQUAD(RGB(ni,ni,ni));}
pal[0]=RGB2RGBQUAD(RGB(0,0,0));
pal[m_nColors-1]=RGB2RGBQUAD(RGB(255,255,255));
memcpy(iDst,ppal,GetPaletteSize());
return;
}
/////////////////////////////////////////////////////////////////////
void CxDib::BlendPalette(COLORREF cr,long perc)
{
if ((hDib==NULL)||(m_nColors==0)) return;
BYTE* iDst = (BYTE*)(hDib) + sizeof(BITMAPINFOHEADER);
long i,r,g,b;
RGBQUAD* pPal=(RGBQUAD*)iDst;
r = GetRValue(cr);
g = GetGValue(cr);
b = GetBValue(cr);
if (perc>100) perc=100;
for(i=0;i<m_nColors;i++){
pPal[i].rgbBlue=(BYTE)((pPal[i].rgbBlue*(100-perc)+b*perc)/100);
pPal[i].rgbGreen =(BYTE)((pPal[i].rgbGreen*(100-perc)+g*perc)/100);
pPal[i].rgbRed =(BYTE)((pPal[i].rgbRed*(100-perc)+r*perc)/100);
}
return;
}
/////////////////////////////////////////////////////////////////////
long CxDib::WriteBMP(LPSTR bmpFileName)
{
if ((*bmpFileName=='\0')||(hDib==0)) return 0;
BITMAPFILEHEADER hdr;
HANDLE hFile;
DWORD nByteWrite;
hFile=CreateFile( // open if exist ini file
bmpFileName, // pointer to name of the file
GENERIC_WRITE, // access mode
0, // share mode
NULL, // pointer to security descriptor
TRUNCATE_EXISTING, // how to create
FILE_ATTRIBUTE_NORMAL, // file attributes
NULL // handle to file with attributes to copy
);
if (hFile==INVALID_HANDLE_VALUE) return 0; //check if file exist
/* Fill in the fields of the file header */
hdr.bfType = BFT_BITMAP;
hdr.bfSize = GetSize() + sizeof(BITMAPFILEHEADER);
hdr.bfReserved1 = hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER)+
m_bi.biSize + GetPaletteSize();
// Write the file header
WriteFile( // write ini (sync mode <-> no overlapped)
hFile, // handle of file to write
(LPSTR) &hdr, // address of buffer that contains data
sizeof(BITMAPFILEHEADER), // number of bytes to write
&nByteWrite, // address of number of bytes written
NULL // address of structure for data
);
// Write the DIB header and the bits
WriteFile( // write ini (sync mode <-> no overlapped)
hFile, // handle of file to write
(LPSTR) hDib, // address of buffer that contains data
GetSize(), // number of bytes to write
&nByteWrite, // address of number of bytes written
NULL // address of structure for data
);
CloseHandle(hFile); //free file handle
return 1;
}
/////////////////////////////////////////////////////////////////////
long CxDib::GetSize()
{
return m_bi.biSize + m_bi.biSizeImage + GetPaletteSize();
}
/////////////////////////////////////////////////////////////////////
BOOL CxDib::IsValid()
{
return (hDib!=NULL);
}
/////////////////////////////////////////////////////////////////////
void CxDib::Clone(CxDib *src)
{
Create(src->GetWidth(),src->GetHeight(),src->GetBitCount());
if (hDib) memcpy(hDib,src->hDib,GetSize());
return;
}
/////////////////////////////////////////////////////////////////////
void CxDib::Clear(BYTE bval)
{
if (hDib) memset(GetBits(),bval,m_bi.biSizeImage);
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CxShadeButton
CxShadeButton::CxShadeButton()
{
m_Border=1; //draw 3D border
m_FocusRectMargin=4; //focus dotted rect margin
m_TextColor=GetSysColor(COLOR_BTNTEXT); // default button text color
m_button_down = m_tracking = false;
}
/////////////////////////////////////////////////////////////////////////////
CxShadeButton::~CxShadeButton()
{ }
/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CxShadeButton, CButton)
//{{AFX_MSG_MAP(CxShadeButton)
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
ON_WM_KILLFOCUS()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
//ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CxShadeButton message handlers
/////////////////////////////////////////////////////////////////////////////
BOOL CxShadeButton::OnEraseBkgnd(CDC* pDC)
{
return 1; // doesn't erase the button background
}
/////////////////////////////////////////////////////////////////////////////
//加入此涵数,在其中为按钮属性初始化时自动添加自画属性(OWNERDRAW)
/////////////////////////////////////////////////////////////////////////////
void CxShadeButton::PreSubclassWindow()
{
SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);
}
/////////////////////////////////////////////////////////////////////////////
void CxShadeButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT (lpDrawItemStruct);
//TRACE("* Captured: %08X\n", ::GetCapture());
//Check if the button state in not in inconsistent mode...
POINT mouse_position;
if ((m_button_down) && (::GetCapture() == m_hWnd) && (::GetCursorPos(&mouse_position))){
if (::WindowFromPoint(mouse_position) == m_hWnd){
if ((GetState() & BST_PUSHED) != BST_PUSHED) {
//TRACE("* Inconsistency up detected! Fixing.\n");
SetState(TRUE);
return;
}
} else {
if ((GetState() & BST_PUSHED) == BST_PUSHED) {
//TRACE("* Inconsistency up detected! Fixing.\n");
SetState(FALSE);
return;
}
}
}
//TRACE("* Drawing: %08x\n", lpDrawItemStruct->itemState);
CString sCaption;
TEXTMETRIC tm;
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); // get device context
RECT r=lpDrawItemStruct->rcItem; // context rectangle
int cx = r.right - r.left ; // get width
int cy = r.bottom - r.top ; // get height
GetWindowText(sCaption); // get button text
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT)); //get text font
pDC->GetTextMetrics(&tm); // get font metrics
// get top-left corner to draw the text centered on the button
int tx=(cx-tm.tmAveCharWidth*sCaption.GetLength())/2;
int ty=(cy-tm.tmHeight)/2;
// Select the correct skin
if (lpDrawItemStruct->itemState & ODS_DISABLED){ // DISABLED BUTTON
if(!m_dDisabled.IsValid())
// no skin selected for disabled state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else // paint the skin
m_dDisabled.Draw(pDC->GetSafeHdc(),0,0);
// if needed, draw the standard 3D rectangular border
if (m_Border) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
// paint the etched button text
pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
pDC->ExtTextOut(tx+1,ty+1,ETO_CLIPPED,&r,sCaption,NULL);
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
pDC->ExtTextOut(tx,ty,ETO_CLIPPED,&r,sCaption,NULL);
} else {
//---------------------------------------------------------------------------
if (lpDrawItemStruct->itemState & ODS_SELECTED){ //SELECTED (DOWN) BUTTON
if(!m_dDown.IsValid())
// no skin selected for selected state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else { // paint the skin
m_dDown.Draw(pDC->GetSafeHdc(),1,1);
}
// if needed, draw the standard 3D rectangular border
if (m_Border) pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT);
} else {
//---------------------------------------------------------------------------
if(!m_dNormal.IsValid()) // DEFAULT BUTTON
// no skin selected for normal state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else // paint the skin
if ((m_tracking)&&(m_dOver.IsValid())){
m_dOver.Draw(pDC->GetSafeHdc(),0,0);
} else {
m_dNormal.Draw(pDC->GetSafeHdc(),0,0);
}
// if needed, draw the standard 3D rectangular border
if (m_Border){
if (lpDrawItemStruct->itemState & ODS_DEFAULT){
pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT);
r.left += 1;
r.top += 1;
r.right -= 1;
r.bottom -= 1;
pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
} else {
pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
}
}
//---------------------------------------------------------------------------
}
// paint the focus rect
if ((lpDrawItemStruct->itemState & ODS_FOCUS)&&(m_FocusRectMargin>0)){
r.left += m_FocusRectMargin ;
r.top += m_FocusRectMargin ;
r.right -= m_FocusRectMargin ;
r.bottom -= m_FocusRectMargin ;
m_dh.Draw(pDC->GetSafeHdc(),r.left,r.top);
m_dh.Draw(pDC->GetSafeHdc(),1+r.left,r.bottom);
m_dv.Draw(pDC->GetSafeHdc(),r.left,1+r.top);
m_dv.Draw(pDC->GetSafeHdc(),r.right,r.top);
}
// paint the enabled button text
pDC->SetTextColor(m_TextColor);
pDC->ExtTextOut(tx,ty,ETO_CLIPPED,&r,sCaption,NULL);
}
}
/////////////////////////////////////////////////////////////////////////////
void CxShadeButton::SetShade(UINT shadeID,BYTE granularity,BYTE highlight,BYTE coloring,COLORREF color)
{
long sXSize,sYSize,bytes,j,i,k,h;
BYTE *iDst ,*posDst;
RECT rect;
GetWindowRect(&rect);
sYSize=rect.bottom-rect.top;
sXSize=rect.right-rect.left ;
m_dh.Create(max(1,sXSize-2*m_FocusRectMargin),1,8); //create the horizontal focus bitmap
m_dv.Create(1,max(1,sYSize-2*m_FocusRectMargin),8); //create the vertical focus bitmap
m_dNormal.Create(sXSize,sYSize,8); //create the default bitmap
COLORREF hicr=GetSysColor(COLOR_BTNHIGHLIGHT); //get the button base colors
COLORREF midcr=GetSysColor(COLOR_BTNFACE);
COLORREF locr=GetSysColor(COLOR_BTNSHADOW);
long r,g,b; //build the shaded palette
for(i=0;i<129;i++){
r=((128-i)*GetRValue(locr)+i*GetRValue(midcr))/128;
g=((128-i)*GetGValue(locr)+i*GetGValue(midcr))/128;
b=((128-i)*GetBValue(locr)+i*GetBValue(midcr))/128;
m_dNormal.SetPaletteIndex((BYTE)i,(BYTE)r,(BYTE)g,(BYTE)b);
m_dh.SetPaletteIndex((BYTE)i,(BYTE)r,(BYTE)g,(BYTE)b);
m_dv.SetPaletteIndex((BYTE)i,(BYTE)r,(BYTE)g,(BYTE)b);
}
for(i=1;i<129;i++){
r=((128-i)*GetRValue(midcr)+i*GetRValue(hicr))/128;
g=((128-i)*GetGValue(midcr)+i*GetGValue(hicr))/128;
b=((128-i)*GetBValue(midcr)+i*GetBValue(hicr))/128;
m_dNormal.SetPaletteIndex((BYTE)(i+127),(BYTE)r,(BYTE)g,(BYTE)b);
m_dh.SetPaletteIndex((BYTE)(i+127),(BYTE)r,(BYTE)g,(BYTE)b);
m_dv.SetPaletteIndex((BYTE)(i+127),(BYTE)r,(BYTE)g,(BYTE)b);
}
m_dNormal.BlendPalette(color,coloring); //color the palette
iDst=m_dh.GetBits(); //build the horiz. dotted focus bitmap
j=(long)m_dh.GetWidth();
for(i=0;i<j;i++){
// iDst[i]=64+127*(i%2); //soft
iDst[i]=255*(i%2); //hard
}
iDst=m_dv.GetBits(); //build the vert. dotted focus bitmap
j=(long)m_dv.GetHeight();
for(i=0;i<j;i++){
// *iDst=64+127*(i%2); //soft
*iDst=255*(i%2); //hard
iDst+=4;
}
bytes = m_dNormal.GetLineWidth();
iDst = m_dNormal.GetBits();
posDst =iDst;
long a,x,y,d,xs,idxmax,idxmin;
int grainx2=RAND_MAX/(max(1,2*granularity));
idxmax=255-granularity;
idxmin=granularity;
switch(shadeID){
//----------------------------------------------------
case 8: //SHS_METAL
m_dNormal.Clear();
// create the strokes
k=40; //stroke granularity
for(a=0;a<200;a++){
x=rand()/(RAND_MAX/sXSize); //stroke postion
y=rand()/(RAND_MAX/sYSize); //stroke position
xs=rand()/(RAND_MAX/min(sXSize,sYSize))/2; //stroke lenght
d=rand()/(RAND_MAX/k); //stroke color
for(i=0;i<xs;i++){
if (((x-i)>0)&&((y+i)<sYSize))
m_dNormal.SetPixelIndex(x-i,y+i,(BYTE)d);
if (((x+i)<sXSize)&&((y-i)>0))
m_dNormal.SetPixelIndex(sXSize-x+i,y-i,(BYTE)d);
}
}
//blend strokes with SHS_DIAGONAL
posDst =iDst;
a=(idxmax-idxmin-k)/2;
for(i = 0; i < sYSize; i++) {
for(j = 0; j < sXSize; j++) {
d=posDst[j]+((a*i)/sYSize+(a*(sXSize-j))/sXSize);
posDst[j]=(BYTE)d;
posDst[j]+=rand()/grainx2;
}
posDst+=bytes;
}
break;
//----------------------------------------------------
case 7: // SHS_HARDBUMP
//set horizontal bump
for(i = 0; i < sYSize; i++) {
k=(255*i/sYSize)-127;
k=(k*(k*k)/128)/128;
k=(k*(128-granularity))/128+128;
for(j = 0; j < sXSize; j++) {
posDst[j]=(BYTE)k;
posDst[j]+=rand()/grainx2-granularity;
}
posDst+=bytes;
}
//set vertical bump
d=min(16,sXSize/6); //max edge=16
a=sYSize*sYSize/4;
posDst =iDst;
for(i = 0; i < sYSize; i++) {
y=i-sYSize/2;
for(j = 0; j < sXSize; j++) {
x=j-sXSize/2;
xs=sXSize/2-d+(y*y*d)/a;
if (x>xs) posDst[j]=idxmin+(BYTE)(((sXSize-j)*128)/d);
if ((x+xs)<0) posDst[j]=idxmax-(BYTE)((j*128)/d);
posDst[j]+=rand()/grainx2-granularity;
}
posDst+=bytes;
}
break;
//----------------------------------------------------
case 6: //SHS_SOFTBUMP
for(i = 0; i < sYSize; i++) {
h=(255*i/sYSize)-127;
for(j = 0; j < sXSize; j++) {
k=(255*(sXSize-j)/sXSize)-127;
k=(h*(h*h)/128)/128+(k*(k*k)/128)/128;
k=k*(128-granularity)/128+128;
if (k<idxmin) k=idxmin;
if (k>idxmax) k=idxmax;
posDst[j]=(BYTE)k;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -