注:资源自由DIY,图片为bmp格式。窗口设置黑色为透明色,所以图片中不想显示的部分都画成黑色
头文件
#pragma once
#include<windows.h>
#include<list>
#include<vector>
#include<string>
using namespace std;
int screenX = GetSystemMetrics(SM_CXSCREEN);
int screenY = GetSystemMetrics(SM_CYSCREEN);
typedef struct rose
{
HBITMAP roseBitmap;
POINT point;
int speed;
}ROSE_STRUCT;
HBITMAP m_Bitmap[3];
list<ROSE_STRUCT> roseList;
vector<string>m_vecStr;//保存所有要显示的文字
int textIndex=0;
POINT textPoint;//当前文字的位置
#include<windows.h>
#include<time.h>
#include"head.h"
#include<list>
#include<vector>
#include <MMSystem.h>
#pragma comment(lib, "WINMM.LIB")
#pragma comment(lib,"msimg32.lib")
using namespace std;
CRITICAL_SECTION cs;
void DrawText(HDC dcMem0);
DWORD WINAPI createThread(LPVOID lpa)
{
srand((unsigned)time(NULL));
while (1)
{
int ImgIndex = rand() % 3;
BITMAP bmp;
GetObject(m_Bitmap[ImgIndex], sizeof(BITMAP),&bmp);
int minX = -bmp.bmWidth / 2;
int maxX = screenX - bmp.bmWidth;
int randXPos = rand()%( maxX - minX + 1) + minX;
int posY = -bmp.bmHeight;
int randSpeed = rand() % 8 + 8;
ROSE_STRUCT rose;
rose.point.x = randXPos;
rose.point.y = posY;
rose.speed = randSpeed;
rose.roseBitmap = m_Bitmap[ImgIndex];
roseList.push_back(rose);
Sleep(100);
}
return 0;
}
DWORD WINAPI drawThread(LPVOID lpa)
{
while (1)
{
HWND hWnd = (HWND)lpa;
HDC hDc,dcMem, tempDC;
HBITMAP hBitmap;
BITMAP bmp;
hDc = GetDC(hWnd);
dcMem = CreateCompatibleDC(hDc);//创建一个兼容DC
tempDC = CreateCompatibleDC(hDc);//创建一个兼容DC
hBitmap = CreateCompatibleBitmap(hDc, screenX, screenY);//创建一个兼容位图
SelectObject(dcMem, hBitmap);
EnterCriticalSection(&cs);
for (list<ROSE_STRUCT>::iterator it = roseList.begin(); it !=roseList.end(); it++)
{
SelectObject(tempDC, it->roseBitmap); //将位图句柄选入临时DC
GetObject(it->roseBitmap, sizeof(BITMAP), &bmp);
//通过位图句柄获取到位图信息,并保存到BITMAP对象中
TransparentBlt(dcMem, it->point.x, it->point.y, bmp.bmWidth, bmp.bmHeight,
tempDC, 0, 0, bmp.bmWidth, bmp.bmHeight, RGB(0,0,0));
}
DrawText(dcMem);
BitBlt(hDc, 0, 0, screenX, screenY, dcMem, 0, 0, SRCCOPY);
LeaveCriticalSection(&cs);
Sleep(100);
DeleteObject(hBitmap);
DeleteObject(dcMem);
DeleteObject(tempDC);
ReleaseDC(hWnd, hDc);
}
return 0;
}
void DrawText(HDC dcMem0)
{
LOGFONT logFont;
ZeroMemory(&logFont, sizeof(logFont));
logFont.lfCharSet = GB2312_CHARSET;
logFont.lfHeight = 80;//文字高度
logFont.lfWidth = 80;//文字宽度
HFONT hFont = CreateFontIndirect(&logFont);
SelectObject(dcMem0, hFont);
SetTextColor(dcMem0, RGB(255, 0, 0));
SetBkMode(dcMem0,TRANSPARENT);
TextOutA(dcMem0, textPoint.x, textPoint.y, m_vecStr[textIndex].c_str(),
m_vecStr[textIndex].size());
DeleteObject(hFont);
}
DWORD WINAPI TextMoveThread(LPVOID lpa)
{
while (1)
{
int textWidth = m_vecStr[textIndex].size() * 80;
textPoint.x = (screenX - textWidth) / 2;//居中显示
textPoint.y += 10;
if (textIndex == 2&&textPoint.y == 600)//最后一段文字就定在中间
{
return 0;
}
if (textPoint.y > screenY)
{
textIndex++;
textPoint.y = -80;
}
Sleep(100);
}
return 0;
}
DWORD WINAPI MoveRoseThread(LPVOID lpa)
{
HWND hwnd = (HWND)lpa;
while (true)
{
for (list<ROSE_STRUCT>::iterator it = roseList.begin(); it != roseList.end();)
{
it->point.y += it->speed;
if (it->point.y > screenY)
{
EnterCriticalSection(&cs);
it = roseList.erase(it);
LeaveCriticalSection(&cs);
continue;
}
it++;
}
// RECT rec = { 0,0,screenX,screenY };
//InvalidateRect(hwnd, &rec,false);
Sleep(100);
}
return 0;
}
DWORD WINAPI playMusicThread(LPVOID lpa)
{
HWND hWnd = (HWND)lpa;
MCIDEVICEID m_dID;
MCI_OPEN_PARMS mciOpen;
// mciOpen.lpstrDeviceType = L"mpegvideo";
mciOpen.lpstrElementName = "res\\1.mp3";
mciOpen.dwCallback = (DWORD)hWnd;
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)(LPVOID)&mciOpen);
m_dID = mciOpen.wDeviceID;
mciSendCommand(m_dID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&mciOpen);
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
HDC dc;
static int cxClient, cyClient;
switch (umsg)
{
case WM_SIZE:
cxClient = LOWORD(lparam);
cyClient = HIWORD(lparam);
break;
case WM_PAINT:
// drawRose(hwnd);
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, umsg, wparam, lparam); //默认的窗口处理函数
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstace, PSTR szCmdLine, int iCmdShow)
{
TCHAR szName[] = "My Windows"; //用于保存窗口类名
HWND hWnd;
MSG msg;
WNDCLASS wnd;
HANDLE hDraw,hCreate,hMove,hMusic,hText;
InitializeCriticalSection(&cs);
wnd.style = CS_VREDRAW | CS_HREDRAW;
wnd.lpfnWndProc = WndProc; //回调函数
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;// 应用程序实例句柄
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wnd.lpszMenuName = NULL;
wnd.lpszClassName = szName; //指定窗口类名
if (!RegisterClass(&wnd))
{
MessageBox(NULL, TEXT("注册窗口失败!"), TEXT("警告"), MB_ICONWARNING);
return 0;
}
hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED, szName, TEXT("class"), WS_POPUP,
0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);
SetLayeredWindowAttributes(hWnd, RGB(0,0,0), 0,LWA_COLORKEY);//设置窗口属性,黑色为透明
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
//加载三个位图并保存在数组中
m_Bitmap[0]= (HBITMAP)LoadImage(NULL, "res\\rose1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_Bitmap[1] = (HBITMAP)LoadImage(NULL, "res\\rose2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_Bitmap[2] = (HBITMAP)LoadImage(NULL, "res\\rose3.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
//容器中保存要显示的文字
m_vecStr.push_back("某某某,I Miss You");
m_vecStr.push_back("做我女朋友可好??");
m_vecStr.push_back("I Love You!!");
textPoint.y = -80;
textPoint.x = 500;
hCreate = CreateThread(NULL, 0, createThread, NULL, 0, 0);
hDraw = CreateThread(NULL, 0, drawThread, hWnd, 0, 0);
hMove = CreateThread(NULL, 0, MoveRoseThread, hWnd, 0, 0);
hMusic = CreateThread(NULL, 0, playMusicThread, hWnd, 0, 0);
hText = CreateThread(NULL, 0, TextMoveThread, hWnd, 0, 0);
while (GetMessage(&msg, 0, 0, 0))//获取到WM_QUIT返回值为0,其他为非0值
{
TranslateMessage(&msg);// 将虚拟键消息转换为字符消息
DispatchMessage(&msg);// 将消息传送到窗口函数
}
DeleteCriticalSection(&cs);
return 0;
}