253 lines
9.4 KiB
C++
253 lines
9.4 KiB
C++
#define UNICODE
|
|
#define _UNICODE
|
|
#include <windows.h>
|
|
#include <gdiplus.h>
|
|
#include <mmsystem.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
using namespace Gdiplus;
|
|
|
|
// ID ресурсов, которые мы прописали в resource.rc
|
|
#define IDR_MEME 101
|
|
#define IDR_SOUND 102
|
|
#define IDR_FART 103
|
|
|
|
// Функция для извлечения "вшитого" в .exe файла во временную папку компьютера
|
|
bool ExtractResourceToFile(int resourceId, const WCHAR* outputPath) {
|
|
HRSRC hRes = FindResourceW(NULL, MAKEINTRESOURCEW(resourceId), (LPCWSTR)RT_RCDATA);
|
|
if (!hRes) return false;
|
|
|
|
HGLOBAL hGlobal = LoadResource(NULL, hRes);
|
|
if (!hGlobal) return false;
|
|
|
|
void* pData = LockResource(hGlobal);
|
|
DWORD size = SizeofResource(NULL, hRes);
|
|
if (!pData || size == 0) return false;
|
|
|
|
HANDLE hFile = CreateFileW(outputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE) return false;
|
|
|
|
DWORD bytesWritten = 0;
|
|
WriteFile(hFile, pData, size, &bytesWritten, NULL);
|
|
CloseHandle(hFile);
|
|
return true;
|
|
}
|
|
|
|
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
|
static Image* image = nullptr;
|
|
static HWND hButton = NULL;
|
|
static bool imageLoaded = false;
|
|
|
|
switch (uMsg) {
|
|
case WM_CREATE: {
|
|
srand((unsigned int)time(NULL));
|
|
|
|
// Громкость на максимум
|
|
for (int i = 0; i < 50; i++) {
|
|
SendMessage(hwnd, WM_APPCOMMAND, (WPARAM)hwnd, MAKELPARAM(0, APPCOMMAND_VOLUME_UP));
|
|
}
|
|
|
|
// Получаем путь к системной временной папке (%TEMP%)
|
|
WCHAR tempDir[MAX_PATH];
|
|
GetTempPathW(MAX_PATH, tempDir);
|
|
|
|
// Формируем пути, куда мы временно распакуем наши вшитые файлы
|
|
WCHAR imgPath[MAX_PATH], soundPath[MAX_PATH], fartPath[MAX_PATH];
|
|
wsprintfW(imgPath, L"%smeme_prank.jpg", tempDir);
|
|
wsprintfW(soundPath, L"%ssound_prank.wav", tempDir);
|
|
wsprintfW(fartPath, L"%sfart_prank.wav", tempDir);
|
|
|
|
// Извлекаем файлы из .exe прямо на диск во временную папку
|
|
ExtractResourceToFile(IDR_MEME, imgPath);
|
|
ExtractResourceToFile(IDR_SOUND, soundPath);
|
|
ExtractResourceToFile(IDR_FART, fartPath);
|
|
|
|
// Теперь загружаем картинку из временной папки
|
|
image = new Image(imgPath);
|
|
if (image && image->GetLastStatus() == Ok) {
|
|
imageLoaded = true;
|
|
}
|
|
|
|
// Загружаем и запускаем звуки из временной папки
|
|
WCHAR cmd[MAX_PATH + 100];
|
|
wsprintfW(cmd, L"open \"%s\" type waveaudio alias mp3", soundPath);
|
|
mciSendStringW(cmd, NULL, 0, NULL);
|
|
mciSendStringW(L"play mp3", NULL, 0, NULL);
|
|
|
|
wsprintfW(cmd, L"open \"%s\" type waveaudio alias fart", fartPath);
|
|
mciSendStringW(cmd, NULL, 0, NULL);
|
|
|
|
// Кнопка закрыть
|
|
hButton = CreateWindowW(
|
|
L"BUTTON", L"Закрыть",
|
|
WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
|
|
300, 300, 150, 50,
|
|
hwnd, (HMENU)1,
|
|
((LPCREATESTRUCT)lParam)->hInstance, NULL);
|
|
|
|
HFONT hFont = CreateFontW(24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
|
|
OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY,
|
|
VARIABLE_PITCH, L"Arial");
|
|
SendMessage(hButton, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
|
|
|
|
SetTimer(hwnd, 1, 20, NULL);
|
|
SetTimer(hwnd, 2, 3000, NULL);
|
|
break;
|
|
}
|
|
|
|
case WM_TIMER: {
|
|
if (wParam == 1 && hButton != NULL) {
|
|
POINT pt;
|
|
GetCursorPos(&pt);
|
|
ScreenToClient(hwnd, &pt);
|
|
|
|
RECT btnRect;
|
|
GetWindowRect(hButton, &btnRect);
|
|
|
|
POINT btnTopLeft = { btnRect.left, btnRect.top };
|
|
POINT btnBottomRight = { btnRect.right, btnRect.bottom };
|
|
ScreenToClient(hwnd, &btnTopLeft);
|
|
ScreenToClient(hwnd, &btnBottomRight);
|
|
|
|
int btnCenterX = btnTopLeft.x + (btnBottomRight.x - btnTopLeft.x) / 2;
|
|
int btnCenterY = btnTopLeft.y + (btnBottomRight.y - btnTopLeft.y) / 2;
|
|
|
|
int dx = pt.x - btnCenterX;
|
|
int dy = pt.y - btnCenterY;
|
|
int distance = sqrt(dx*dx + dy*dy);
|
|
|
|
if (distance < 150) {
|
|
RECT clientRect;
|
|
GetClientRect(hwnd, &clientRect);
|
|
int btnWidth = btnBottomRight.x - btnTopLeft.x;
|
|
int btnHeight = btnBottomRight.y - btnTopLeft.y;
|
|
int newX = rand() % (clientRect.right - btnWidth);
|
|
int newY = rand() % (clientRect.bottom - btnHeight);
|
|
SetWindowPos(hButton, NULL, newX, newY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
InvalidateRect(hwnd, NULL, !imageLoaded);
|
|
}
|
|
else if (wParam == 2) {
|
|
mciSendStringW(L"play fart from 0", NULL, 0, NULL);
|
|
KillTimer(hwnd, 2);
|
|
int nextInterval = (rand() % 5000) + 3000;
|
|
SetTimer(hwnd, 2, nextInterval, NULL);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == 1) {
|
|
RECT clientRect;
|
|
GetClientRect(hwnd, &clientRect);
|
|
int newX = rand() % (clientRect.right - 150);
|
|
int newY = rand() % (clientRect.bottom - 50);
|
|
SetWindowPos(hButton, NULL, newX, newY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
return 0;
|
|
|
|
case WM_PAINT: {
|
|
PAINTSTRUCT ps;
|
|
HDC hdc = BeginPaint(hwnd, &ps);
|
|
|
|
if (imageLoaded) {
|
|
Graphics graphics(hdc);
|
|
RECT rc;
|
|
GetClientRect(hwnd, &rc);
|
|
|
|
int shakeX = (rand() % 31) - 15;
|
|
int shakeY = (rand() % 31) - 15;
|
|
graphics.DrawImage(image, shakeX - 15, shakeY - 15, rc.right + 30, rc.bottom + 30);
|
|
} else {
|
|
HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
|
|
RECT rc;
|
|
GetClientRect(hwnd, &rc);
|
|
FillRect(hdc, &rc, redBrush);
|
|
DeleteObject(redBrush);
|
|
|
|
SetBkMode(hdc, TRANSPARENT);
|
|
SetTextColor(hdc, RGB(255,255,255));
|
|
DrawTextW(hdc, L"ОШИБКА РАСПАКОВКИ: КАРТИНКА НЕ НАЙДЕНА!", -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
|
}
|
|
|
|
EndPaint(hwnd, &ps);
|
|
return 0;
|
|
}
|
|
|
|
case WM_KEYDOWN:
|
|
if (wParam == VK_ESCAPE) {
|
|
DestroyWindow(hwnd);
|
|
}
|
|
return 0;
|
|
|
|
case WM_DESTROY: {
|
|
KillTimer(hwnd, 1);
|
|
KillTimer(hwnd, 2);
|
|
|
|
mciSendStringW(L"close mp3", NULL, 0, NULL);
|
|
mciSendStringW(L"close fart", NULL, 0, NULL);
|
|
if (image) delete image;
|
|
|
|
// Удаляем временные файлы после закрытия, чтобы не мусорить
|
|
WCHAR tempDir[MAX_PATH], imgPath[MAX_PATH], soundPath[MAX_PATH], fartPath[MAX_PATH];
|
|
GetTempPathW(MAX_PATH, tempDir);
|
|
wsprintfW(imgPath, L"%smeme_prank.jpg", tempDir);
|
|
wsprintfW(soundPath, L"%ssound_prank.wav", tempDir);
|
|
wsprintfW(fartPath, L"%sfart_prank.wav", tempDir);
|
|
DeleteFileW(imgPath);
|
|
DeleteFileW(soundPath);
|
|
DeleteFileW(fartPath);
|
|
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
}
|
|
}
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
|
GdiplusStartupInput gdiplusStartupInput;
|
|
ULONG_PTR gdiplusToken;
|
|
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
|
|
|
|
const WCHAR CLASS_NAME[] = L"PrankWindow";
|
|
|
|
WNDCLASSW wc = {0};
|
|
wc.lpfnWndProc = WindowProc;
|
|
wc.hInstance = hInstance;
|
|
wc.lpszClassName = CLASS_NAME;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|
|
|
RegisterClassW(&wc);
|
|
|
|
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
HWND hwnd = CreateWindowExW(
|
|
WS_EX_TOPMOST,
|
|
CLASS_NAME,
|
|
L"Prank",
|
|
WS_POPUP | WS_VISIBLE,
|
|
0, 0, screenWidth, screenHeight,
|
|
NULL, NULL, hInstance, NULL
|
|
);
|
|
|
|
if (hwnd == NULL) {
|
|
GdiplusShutdown(gdiplusToken);
|
|
return 0;
|
|
}
|
|
|
|
MSG msg;
|
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
GdiplusShutdown(gdiplusToken);
|
|
return 0;
|
|
}
|