📄 transparentwnd.cpp
字号:
//////////////////////////////////////////////////
//类名:CTransparentWnd
//功能:透明窗体实现
//作者:徐景周(jingzhou_xu@163.net)
//组织:未来工作室(Future Studio)
//日期:2001.12.1
//////////////////////////////////////////////////
#include "stdafx.h"
#include "TransparentWnd.h"
#include <assert.h>
#include "HelpTip.h"
#include "HelpTipDlg.h"
#include "DownloadAddress.h"
#include "About.h"
#include "SetRing.h"
#include "Advertise.h"
#include "Splash.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TIMER_SET 1
#define TIMER_WALK 2
#define TIMER_IDLE 3
#define TIMER_RUN 4
#define TIMER_PLAYSOUND 5
#define TIMER_DRAGDROP 6
#define TIMER_TRANSFORM 7
#define TIMER_SETRING 8
#define TIMER_FALL 9
#define WM_TRAYNOTIFY WM_USER + 100 //自定义系统托盘消息函数
CAdvertise *m_pADdlg ; //广告窗体
//设置开机程序自启动键值位置和其下新建子键值(可设为程序名)
const TCHAR gcszAutoRunKey[]= _T( "Software\\Microsoft\\windows\\CurrentVersion\\Run" );
const TCHAR gcszWindowClass[] = _T("Man");
//********************************************************************************
//* 名称:CTransparentWnd()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:构造涵数,在此初始化变量
//********************************************************************************
CTransparentWnd::CTransparentWnd()
{
m_iAniSeq=0;
strPath="";
m_bSuccess=FALSE;
}
//********************************************************************************
//* 名称:~CTransparentWnd()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:析构涵数,可在此删除创建的变量
//********************************************************************************
CTransparentWnd::~CTransparentWnd()
{
//消毁广告窗体
if ( m_pADdlg != NULL )
{
delete m_pADdlg;
m_pADdlg = NULL;
}
}
BEGIN_MESSAGE_MAP(CTransparentWnd, CWnd)
//{{AFX_MSG_MAP(CTransparentWnd)
ON_MESSAGE(WM_TRAYNOTIFY, OnTrayNotification) //自定义系统托盘消息涵数
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_DESTROY()
ON_WM_RBUTTONDOWN()
ON_COMMAND(IDR_EXIT, OnExit)
ON_COMMAND(IDR_FULLSCREEN_WALK, OnFullscreenWalk)
ON_UPDATE_COMMAND_UI(IDR_FULLSCREEN_WALK, OnUpdateFullscreenWalk)
ON_COMMAND(IDR_SHOWHIDE, OnShowhide)
ON_WM_INITMENUPOPUP()
ON_COMMAND(IDR_DOWNLOAD, OnDownload)
ON_COMMAND(IDR_ACTION_RUN, OnActionRun)
ON_COMMAND(IDR_ACTION_WALK, OnActionWalk)
ON_COMMAND(IDR_ACTION_IDLE, OnActionIdle)
ON_WM_MEASUREITEM()
ON_WM_MENUCHAR()
ON_COMMAND(IDR_ABOUT, OnAbout)
ON_WM_LBUTTONUP()
ON_COMMAND(IDR_OPTION_MUTE, OnOptionMute)
ON_COMMAND(IDR_OPTION_REST, OnOptionRest)
ON_COMMAND(IDR_OPTION_TOPSHOW, OnOptionTopshow)
ON_COMMAND(IDR_ACTION_SPECIAL, OnActionSpecial)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(IDR_AUTORUN, OnAutorun)
ON_COMMAND(IDR_SHOWNEWS, OnShownews)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//********************************************************************************
//* 名称:CreateTransparent()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:建立透明窗体
//********************************************************************************
void CTransparentWnd::CreateTransparent(LPCTSTR pTitle, RECT &rect)
{
CreateEx( 0,
AfxRegisterWndClass(0,AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
pTitle,
WS_POPUP ,
rect,
NULL,
NULL,
NULL );
}
//********************************************************************************
//* 名称:GetSourceHtml()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:下载网页涵数
//********************************************************************************
BOOL CTransparentWnd::GetSourceHtml(CString theUrl,CString Filename)
{
CInternetSession session;
CInternetFile* file = NULL;
try
{
// 试着连接到指定URL
file = (CInternetFile*) session.OpenURL(theUrl);
}
catch (CInternetException* m_pException)
{
// 如果有错误的话,置文件为空
file = NULL;
m_pException->Delete();
return FALSE;
}
// 用dataStore来保存读取的网页文件
CStdioFile dataStore;
if (file)
{
CString somecode; //也可采用LPTSTR类型,将不会删除文本中的\n回车符
BOOL bIsOk = dataStore.Open(strPath+"\\"+Filename,
CFile::modeCreate
| CFile::modeWrite
| CFile::shareDenyWrite
| CFile::typeText);
if (!bIsOk)
return FALSE;
// 读写网页文件,直到为空
while (file->ReadString(somecode) != NULL) //如果采用LPTSTR类型,读取最大个数nMax置0,使它遇空字符时结束
{
dataStore.WriteString(somecode);
dataStore.WriteString("\n"); //如果somecode采用LPTSTR类型,可不用此句
}
file->Close();
delete file;
}
else
{
dataStore.WriteString(_T("到指定服务器的连接建立失败..."));
return FALSE;
}
return TRUE;
}
//********************************************************************************
//* 名称:SoundPlay()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:播放内镶WAV声音文件
//********************************************************************************
void CTransparentWnd::SoundPlay(void)
{
//先关闭原声音播放
PlaySound("IDR_WAVE",AfxGetResourceHandle(),SND_RESOURCE|SND_PURGE|SND_NODEFAULT );
//设置播放声音时间0.84秒
SetTimer(TIMER_PLAYSOUND,840,NULL);
//资源WAV文件的ID须加双引号,用下API函数播放
PlaySound("IDR_WAVE",AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC|SND_NODEFAULT );
}
//********************************************************************************
//* 名称:SetupRegion()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:将窗体背景透明化(新的透明算法)
//********************************************************************************
void CTransparentWnd::SetupRegion(CDC *pDC)
{
HRGN hRgn = NULL;
CBitmap &cBitmap=m_bmpDraw;
CRect cRect;
GetWindowRect(&cRect);
CPoint ptOrg=cRect.TopLeft();
// 获取位图大小
BITMAP bm;
cBitmap.GetObject(sizeof(bm),&bm);
CRect rcNewWnd=CRect(ptOrg,CSize(bm.bmWidth,bm.bmHeight));
// 创建兼容DC,只便扫描它的元素
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
{
// 创建一32位位图,并放到兼容DC中
BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
sizeof(BITMAPINFOHEADER), // biSize
bm.bmWidth, // biWidth;
bm.bmHeight, // biHeight;
1, // biPlanes;
32, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
};
VOID * pbits32;
HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
if (hbm32)
{
HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
// 创建DC,放位图到它里面
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
{
// 获取每行多少位
BITMAP bm32;
GetObject(hbm32, sizeof(bm32), &bm32);
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
// 复制位图到兼容DC中
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, (HBITMAP)cBitmap );
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
COLORREF cTolerance = 0x101010;
COLORREF cTransparentColor=::GetPixel(hDC,0,0);
// 为了更好的实现,将使用 ExtCreateRegion() 涵数来创建一区域,这个涵数要用来
// RGNDATA 结构. 我们将用ALLOC_UNI来添加矩形框。
#define ALLOC_UNIT 100
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
// 为了获得透明像素,要分别保留其要透明背景色的最高、最低值
BYTE lr = GetRValue(cTransparentColor);
BYTE lg = GetGValue(cTransparentColor);
BYTE lb = GetBValue(cTransparentColor);
BYTE hr = min(0xff, lr + GetRValue(cTolerance));
BYTE hg = min(0xff, lg + GetGValue(cTolerance));
BYTE hb = min(0xff, lb + GetBValue(cTolerance));
// 从下往上扫描每一个位图(位图是竖直反方向的)
BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
{
// 从左往右扫描每一个像素
for (int x = 0; x < bm.bmWidth; x++)
{
// 连续搜索非透明元素
int x0 = x;
LONG *p = (LONG *)p32 + x;
while (x < bm.bmWidth)
{
BYTE b = GetRValue(*p);
if (b >= lr && b <= hr)
{
b = GetGValue(*p);
if (b >= lg && b <= hg)
{
b = GetBValue(*p);
if (b >= lb && b <= hb)
// 如果是透明元素的话
break;
}
}
p++;
x++;
}
if (x > x0)
{
// 添加像素(x0, y) 到 (x, y+1) ,作为区域中的新矩形
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;
// 在Windows98中, 如果矩形数太多的话(ie: > 4000),ExtCreateRegion()涵数可能失败.
// 因此,我们必须通过多步来创建矩形。
if (pData->rdh.nCount == 2000)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// 到下一行(注意: 位图是竖直反方向的)
p32 -= bm32.bmWidthBytes;
}
// 根据保留的矩形来创建或廷伸区域
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
// 释放
GlobalFree(hData);
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
SetWindowRgn(hRgn, TRUE);
MoveWindow(rcNewWnd);
}
//********************************************************************************
//* 名称:DoSet()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:判断该进行何种运行方式
//********************************************************************************
void CTransparentWnd::DoSet(void)
{
int iSW=GetSystemMetrics(SM_CXFULLSCREEN);
int iSH=GetSystemMetrics(SM_CYFULLSCREEN);
KillTimer(TIMER_SET);
switch(rand()%5)
{
case(0): //散步
case(1):
case(2):
m_ptDest.x=rand()%(iSW - 10);
m_ptDest.y=rand()%(iSH - 10);
SetTimer(TIMER_WALK,150,NULL);
break;
case(3): //奔跑
SetTimer(TIMER_TRANSFORM,300,NULL); //改原奔跑为变形状态
// m_ptDest.x=rand()%(iSW - 10);
// m_ptDest.y=rand()%(iSH - 10);
// SetTimer(TIMER_RUN,500,NULL);
break;
case(4): //休息
SetTimer(TIMER_IDLE,300,NULL);
break;
}
}
//********************************************************************************
//* 名称:DoWalk()
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:散步
//********************************************************************************
void CTransparentWnd::DoWalk(void)
{
if(!m_bRest) //如果不是静止的话
{
char szBmp[20];
CRect rcW;
GetWindowRect(rcW);
//决定全屏或局部运动的范围,暂只考虑任务条在下方时情况
if(m_bFullScreenWalk)
{
if((m_ptDest.x> rcW.left && m_ptDest.x < rcW.right)||(m_ptDest.y> rcW.top && m_ptDest.y < rcW.bottom ))
{
KillTimer(TIMER_WALK);
SetTimer(TIMER_SET,10,NULL);
return;
}
//设置精灵行走步长
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -