在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口
2007-03-17 21:58:56 来源:WEB开发网核心提示: BOOL CGDIPClockDlg::UpdateClockDisplay(int Transparent){ HDC hdcTemp=GetDC()->m_hDC; m_hdcMemory=CreateCompatibleDC(hdcTemp); HBITMAP hBitMap=
BOOL CGDIPClockDlg::UpdateClockDisplay(int Transparent)
{
HDC hdcTemp=GetDC()->m_hDC;
m_hdcMemory=CreateCompatibleDC(hdcTemp);
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,m_BakWidth,m_BakHeight);
SelectObject(m_hdcMemory,hBitMap);
if(Transparent<0||Transparent>100) Transparent=100;
m_Blend.SourceConstantAlpha=int(Transparent*2.55);
HDC hdcScreen=::GetDC (m_hWnd);
RECT rct;
GetWindowRect(&rct);
POINT ptWinPos={rct.left,rct.top};
Graphics graph(m_hdcMemory);
Point points[] = { Point(0, 0),
Point(m_BakWidth, 0),
Point(0, m_BakHeight)
};
static bool bFly=false;
bFly?graph.DrawImage(m_pImageClock, points, 3): graph.DrawImage(m_pImageClock1, points, 3);
bFly=!bFly;
int OxyX=140;//m_BakWidth/2+8;
int OxyY=90;//m_BakHeight/2+10;
SYSTEMTIME SystemTime; // address of system time structure
GetLocalTime(&SystemTime);
// 定义一个单位矩阵,坐标原点在表盘中央
Matrix matrixH(1,0,0,1,OxyX,OxyY);
// 时针旋转的角度度
matrixH.Rotate(SystemTime.wHour*30+SystemTime.wMinute/2.0-180);
Point pointsH[] = { Point(0, 0),Point(m_HourWidth, 0),Point(0, m_HourHeight)};
matrixH.Translate(-m_HourWidth/2,-m_HourHeight/6);
// 用该矩阵转换points
matrixH.TransformPoints( pointsH, 3);
graph.DrawImage (m_pImageHHour,pointsH, 3);
// 定义一个单位矩阵,坐标原点在表盘中央
Matrix matrixM(1,0,0,1,OxyX,OxyY);
// 分针旋转的角度度
matrixM.Rotate(SystemTime.wMinute*6-180);
Point pointsM[] = { Point(0, 0),Point(m_MinuWidth, 0),Point(0, m_MinuHeight)};
matrixM.Translate(-m_MinuWidth/2,-m_MinuHeight/6);
// 用该矩阵转换pointsM
matrixM.TransformPoints( pointsM, 3);
graph.DrawImage (m_pImageHMinu,pointsM, 3);
// 定义一个单位矩阵,坐标原点在表盘中央
Matrix matrix(1,0,0,1,OxyX,OxyY);
// 秒针旋转的角度度
matrix.Rotate(SystemTime.wSecond*6-180);
Point pointsS[] = { Point(0, 0),Point( m_SecWidth,0),Point(0,m_SecHeight )};
matrix.Translate(-m_SecWidth/2,-m_SecHeight/7);
// 用该矩阵转换pointsS
matrix.TransformPoints( pointsS, 3);
graph.DrawImage (m_pImageHSec,pointsS, 3);
//HH:MM:SS
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,0, 0, 14*(SystemTime.wHour/10), 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20,0, 14*(SystemTime.wHour%10), 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20*2,0, 140, 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20*3, 0, 14*(SystemTime.wMinute/10), 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20*4,0, 14*(SystemTime.wMinute%10), 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20*5,0, 140, 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20*6, 0, 14*(SystemTime.wSecond/10), 0,14,23,UnitPixel);
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum,20*7,0, 14*(SystemTime.wSecond%10), 0,14,23,UnitPixel);
SIZE sizeWindow={m_BakWidth,m_BakHeight};
POINT ptSrc={0,0};
DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE);
if((dwExStyle&0x80000)!=0x80000)
SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);
BOOL bRet=FALSE;
bRet= UpdateLayeredWindow( m_hWnd,hdcScreen,&ptWinPos,
&sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2);
graph.ReleaseHDC(m_hdcMemory);
::ReleaseDC(m_hWnd,hdcScreen);
hdcScreen=NULL;
::ReleaseDC(m_hWnd,hdcTemp);
hdcTemp=NULL;
DeleteObject(hBitMap);
DeleteDC(m_hdcMemory);
m_hdcMemory=NULL;
return bRet;
}
BOOL CGDIPClockDlg::ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
if (!hRsrc)
return FALSE;
// load resource into memory
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!lpRsrc)
return FALSE;
// Allocate global memory on which to create stream
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,lpRsrc,len);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
// load from stream
pImg=Gdiplus::Image::FromStream(pstm);
// free/release stuff
GlobalUnlock(m_hMem);
pstm->Release();
FreeResource(lpRsrc);
}
void CGDIPClockDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
//禁止显示移动矩形窗体框
::SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,TRUE,NULL,0);
//非标题栏移动整个窗口
SendMessage(WM_SYSCOMMAND,0xF012,0);
// PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
CDialog::OnLButtonDown(nFlags, point);
}
详细实现过程请参考源代码!四、结束语
编写该程序的主要动力来自于对GDI+图像、图形功能的好奇,网上好多例子和文章都是关于C#或delphi等语言的。本人一直以来习惯于使用VC6.0。希望通过此文能增进与大家交流。
更多精彩
赞助商链接