mirror of
https://forgejo.xatacraft.ru/Sunshine/mkxp-sunshine.git
synced 2026-08-19 13:29:54 +00:00
Added active? function, fixed CRLF line endings
This commit is contained in:
parent
78c4c3b9bf
commit
6312ce865c
4 changed files with 336 additions and 326 deletions
|
|
@ -11,6 +11,7 @@ static SDL_Thread *thread = NULL;
|
|||
static SDL_mutex *mutex = NULL;
|
||||
static volatile char message_buffer[OUT_BUFFER_SIZE];
|
||||
static volatile int message_len = 0;
|
||||
static volatile bool active = false;
|
||||
|
||||
int server_thread(void *data)
|
||||
{
|
||||
|
|
@ -27,6 +28,7 @@ int server_thread(void *data)
|
|||
ConnectNamedPipe(pipe, NULL);
|
||||
SDL_LockMutex(mutex);
|
||||
WriteFile(pipe, (const void*)message_buffer, OUT_BUFFER_SIZE, NULL, NULL);
|
||||
active = true;
|
||||
SDL_UnlockMutex(mutex);
|
||||
FlushFileBuffers(pipe);
|
||||
DisconnectNamedPipe(pipe);
|
||||
|
|
@ -59,6 +61,7 @@ RB_METHOD(journalSet)
|
|||
message_len = len;
|
||||
SDL_UnlockMutex(mutex);
|
||||
if (pipe != INVALID_HANDLE_VALUE) {
|
||||
active = true;
|
||||
WriteFile(pipe, (const void*)message_buffer, OUT_BUFFER_SIZE, NULL, NULL);
|
||||
FlushFileBuffers(pipe);
|
||||
CloseHandle(pipe);
|
||||
|
|
@ -67,10 +70,16 @@ RB_METHOD(journalSet)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
RB_METHOD(journalActive)
|
||||
{
|
||||
return active ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
void journalBindingInit()
|
||||
{
|
||||
mutex = SDL_CreateMutex();
|
||||
|
||||
VALUE module = rb_define_module("Journal");
|
||||
_rb_define_module_function(module, "set", journalSet);
|
||||
_rb_define_module_function(module, "active?", journalActive);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,169 +1,170 @@
|
|||
#include <windows.h>
|
||||
|
||||
#define DEFAULT_WIDTH 800
|
||||
#define DEFAULT_HEIGHT 600
|
||||
#define IN_BUFFER_SIZE 256
|
||||
|
||||
static const WCHAR journal_classname[] = L"journal";
|
||||
|
||||
static HBITMAP image_handle = NULL;
|
||||
static HANDLE image_mutex = NULL;
|
||||
|
||||
static HWND window = NULL;
|
||||
|
||||
static void loadImage(const char *name) {
|
||||
if (image_handle) {
|
||||
DeleteObject(image_handle);
|
||||
}
|
||||
image_handle = LoadBitmapA(GetModuleHandleW(NULL), name);
|
||||
}
|
||||
|
||||
// Window procedure
|
||||
LRESULT CALLBACK journal_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
HDC hdcMem;
|
||||
|
||||
WaitForSingleObject(image_mutex, INFINITE);
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
hdcMem = CreateCompatibleDC(hdc);
|
||||
HANDLE oldBitmap = SelectObject(hdcMem, image_handle);
|
||||
BitBlt(hdc, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT, hdcMem, 0, 0, SRCCOPY);
|
||||
SelectObject(hdcMem, oldBitmap);
|
||||
DeleteDC(hdcMem);
|
||||
EndPaint(hwnd, &ps);
|
||||
ReleaseMutex(image_mutex);
|
||||
} break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IPC thread
|
||||
#include <stdio.h>
|
||||
DWORD WINAPI ipc_thread(LPVOID lpParam)
|
||||
{
|
||||
(void)lpParam;
|
||||
|
||||
char message[IN_BUFFER_SIZE];
|
||||
DWORD len;
|
||||
|
||||
HANDLE pipe = CreateNamedPipeW(L"\\\\.\\pipe\\oneshot-game-to-journal",
|
||||
PIPE_ACCESS_INBOUND,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
IN_BUFFER_SIZE,
|
||||
IN_BUFFER_SIZE,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
for (;;) {
|
||||
if (!ConnectNamedPipe(pipe, NULL))
|
||||
continue;
|
||||
for (;;) {
|
||||
if (ReadFile(pipe, (void*)message, IN_BUFFER_SIZE, &len, NULL)
|
||||
&& len == IN_BUFFER_SIZE)
|
||||
{
|
||||
WaitForSingleObject(image_mutex, INFINITE);
|
||||
if (strcmp(message, "default") == 0) {
|
||||
exit(0);
|
||||
}
|
||||
loadImage(message);
|
||||
InvalidateRect(window, NULL, FALSE);
|
||||
ReleaseMutex(image_mutex);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DisconnectNamedPipe(pipe);
|
||||
}
|
||||
|
||||
CloseHandle(pipe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_journal()
|
||||
{
|
||||
// Create
|
||||
HINSTANCE module = GetModuleHandleW(NULL);
|
||||
|
||||
loadImage("default");
|
||||
|
||||
// Initial image
|
||||
char message[IN_BUFFER_SIZE];
|
||||
DWORD len;
|
||||
HANDLE pipe = CreateFileW(L"\\\\.\\pipe\\oneshot-journal-to-game",
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (pipe != INVALID_HANDLE_VALUE) {
|
||||
if (ReadFile(pipe, (void*)message, IN_BUFFER_SIZE, &len, NULL)
|
||||
&& len == IN_BUFFER_SIZE)
|
||||
{
|
||||
loadImage(message);
|
||||
}
|
||||
CloseHandle(pipe);
|
||||
}
|
||||
|
||||
WNDCLASSEXW wc;
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = journal_proc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = module;
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = journal_classname;
|
||||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
if (!RegisterClassEx(&wc))
|
||||
return 1;
|
||||
|
||||
if (!(window = CreateWindowExW(WS_EX_COMPOSITED | WS_EX_LAYERED | WS_EX_TOPMOST,
|
||||
journal_classname,
|
||||
L"",
|
||||
WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MAXIMIZEBOX),
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT,
|
||||
NULL, NULL, module, NULL))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SetLayeredWindowAttributes(window, RGB(0, 255, 0), 0, LWA_COLORKEY);
|
||||
|
||||
ShowWindow(window, SW_SHOWNOACTIVATE);
|
||||
UpdateWindow(window);
|
||||
|
||||
image_mutex = CreateMutexW(NULL, NULL, NULL);
|
||||
HANDLE thread = CreateThread(NULL, 0, ipc_thread, NULL, 0, NULL);
|
||||
|
||||
// Dispatch messages
|
||||
for (;;) {
|
||||
MSG msg;
|
||||
if (GetMessage(&msg, window, 0, 0) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO make this less messy?
|
||||
TerminateThread(thread, 0);
|
||||
|
||||
DestroyWindow(window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include <windows.h>
|
||||
|
||||
#define DEFAULT_WIDTH 800
|
||||
#define DEFAULT_HEIGHT 600
|
||||
#define IN_BUFFER_SIZE 256
|
||||
|
||||
static const WCHAR journal_classname[] = L"journal";
|
||||
|
||||
static HBITMAP image_handle = NULL;
|
||||
static HANDLE image_mutex = NULL;
|
||||
|
||||
static HWND window = NULL;
|
||||
|
||||
static void loadImage(const char *name) {
|
||||
if (image_handle) {
|
||||
DeleteObject(image_handle);
|
||||
}
|
||||
image_handle = LoadBitmapA(GetModuleHandleW(NULL), name);
|
||||
}
|
||||
|
||||
// Window procedure
|
||||
LRESULT CALLBACK journal_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
HDC hdcMem;
|
||||
|
||||
WaitForSingleObject(image_mutex, INFINITE);
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
hdcMem = CreateCompatibleDC(hdc);
|
||||
HANDLE oldBitmap = SelectObject(hdcMem, image_handle);
|
||||
BitBlt(hdc, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT, hdcMem, 0, 0, SRCCOPY);
|
||||
SelectObject(hdcMem, oldBitmap);
|
||||
DeleteDC(hdcMem);
|
||||
EndPaint(hwnd, &ps);
|
||||
ReleaseMutex(image_mutex);
|
||||
} break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IPC thread
|
||||
#include <stdio.h>
|
||||
DWORD WINAPI ipc_thread(LPVOID lpParam)
|
||||
{
|
||||
(void)lpParam;
|
||||
|
||||
char message[IN_BUFFER_SIZE];
|
||||
DWORD len;
|
||||
|
||||
HANDLE pipe = CreateNamedPipeW(L"\\\\.\\pipe\\oneshot-game-to-journal",
|
||||
PIPE_ACCESS_INBOUND,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
IN_BUFFER_SIZE,
|
||||
IN_BUFFER_SIZE,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
for (;;) {
|
||||
if (!ConnectNamedPipe(pipe, NULL))
|
||||
continue;
|
||||
for (;;) {
|
||||
if (ReadFile(pipe, (void*)message, IN_BUFFER_SIZE, &len, NULL)
|
||||
&& len == IN_BUFFER_SIZE)
|
||||
{
|
||||
WaitForSingleObject(image_mutex, INFINITE);
|
||||
if (*message == 0) {
|
||||
exit(0);
|
||||
}
|
||||
loadImage(message);
|
||||
InvalidateRect(window, NULL, FALSE);
|
||||
ReleaseMutex(image_mutex);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DisconnectNamedPipe(pipe);
|
||||
}
|
||||
|
||||
CloseHandle(pipe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_journal()
|
||||
{
|
||||
// Create
|
||||
HINSTANCE module = GetModuleHandleW(NULL);
|
||||
|
||||
loadImage("default");
|
||||
|
||||
// Initial image
|
||||
char message[IN_BUFFER_SIZE];
|
||||
DWORD len;
|
||||
HANDLE pipe = CreateFileW(L"\\\\.\\pipe\\oneshot-journal-to-game",
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (pipe != INVALID_HANDLE_VALUE) {
|
||||
if (ReadFile(pipe, (void*)message, IN_BUFFER_SIZE, &len, NULL)
|
||||
&& len == IN_BUFFER_SIZE)
|
||||
{
|
||||
if (*message)
|
||||
loadImage(message);
|
||||
}
|
||||
CloseHandle(pipe);
|
||||
}
|
||||
|
||||
WNDCLASSEXW wc;
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = journal_proc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = module;
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = journal_classname;
|
||||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
if (!RegisterClassEx(&wc))
|
||||
return 1;
|
||||
|
||||
if (!(window = CreateWindowExW(WS_EX_COMPOSITED | WS_EX_LAYERED | WS_EX_TOPMOST,
|
||||
journal_classname,
|
||||
L"",
|
||||
WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MAXIMIZEBOX),
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT,
|
||||
NULL, NULL, module, NULL))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SetLayeredWindowAttributes(window, RGB(0, 255, 0), 0, LWA_COLORKEY);
|
||||
|
||||
ShowWindow(window, SW_SHOWNOACTIVATE);
|
||||
UpdateWindow(window);
|
||||
|
||||
image_mutex = CreateMutexW(NULL, NULL, NULL);
|
||||
HANDLE thread = CreateThread(NULL, 0, ipc_thread, NULL, 0, NULL);
|
||||
|
||||
// Dispatch messages
|
||||
for (;;) {
|
||||
MSG msg;
|
||||
if (GetMessage(&msg, window, 0, 0) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO make this less messy?
|
||||
TerminateThread(thread, 0);
|
||||
|
||||
DestroyWindow(window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
#include <windows.h>
|
||||
|
||||
extern int do_niko(int x, int y);
|
||||
extern int do_journal();
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)hPrevInstance;
|
||||
(void)lpCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
int argc;
|
||||
LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
// argc == 3, assume niko
|
||||
if (argc == 3) {
|
||||
int x = _wtoi(argv[1]);
|
||||
int y = _wtoi(argv[2]);
|
||||
return do_niko(x, y);
|
||||
}
|
||||
// assume journal
|
||||
return do_journal();
|
||||
}
|
||||
#include <windows.h>
|
||||
|
||||
extern int do_niko(int x, int y);
|
||||
extern int do_journal();
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)hPrevInstance;
|
||||
(void)lpCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
int argc;
|
||||
LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
// argc == 3, assume niko
|
||||
if (argc == 3) {
|
||||
int x = _wtoi(argv[1]);
|
||||
int y = _wtoi(argv[2]);
|
||||
return do_niko(x, y);
|
||||
}
|
||||
// assume journal
|
||||
return do_journal();
|
||||
}
|
||||
|
|
|
|||
260
journal/niko.cpp
260
journal/niko.cpp
|
|
@ -1,130 +1,130 @@
|
|||
#include <windows.h>
|
||||
|
||||
static const WCHAR niko_classname[] = L"niko";
|
||||
static HWND niko = NULL;
|
||||
static HBITMAP niko_bmps[3] = {NULL};
|
||||
static int niko_offset = 0;
|
||||
|
||||
// Window procedure
|
||||
LRESULT CALLBACK niko_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_CLOSE:
|
||||
return 0;
|
||||
|
||||
case WM_PAINT: {
|
||||
static int frame = 0;
|
||||
if (niko_offset % 32 >= 16) {
|
||||
frame = 1;
|
||||
} else {
|
||||
if ((niko_offset / 32) % 2)
|
||||
frame = 0;
|
||||
else
|
||||
frame = 2;
|
||||
}
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
BITMAP bitmap;
|
||||
HDC hdcMem;
|
||||
HGDIOBJ oldBitmap;
|
||||
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
hdcMem = CreateCompatibleDC(hdc);
|
||||
oldBitmap = SelectObject(hdcMem, niko_bmps[frame]);
|
||||
|
||||
GetObject(niko_bmps[frame], sizeof(bitmap), &bitmap);
|
||||
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
|
||||
|
||||
SelectObject(hdcMem, oldBitmap);
|
||||
DeleteDC(hdcMem);
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_niko(int x, int y)
|
||||
{
|
||||
// Create
|
||||
HINSTANCE module = GetModuleHandleW(NULL);
|
||||
niko_bmps[0] = LoadBitmapW(module, L"NIKO1");
|
||||
niko_bmps[1] = LoadBitmapW(module, L"NIKO2");
|
||||
niko_bmps[2] = LoadBitmapW(module, L"NIKO3");
|
||||
|
||||
WNDCLASSEXW wc;
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = niko_proc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = module;
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = niko_classname;
|
||||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
if (!RegisterClassEx(&wc))
|
||||
return 1;
|
||||
|
||||
if (!(niko = CreateWindowExW(WS_EX_COMPOSITED | WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
|
||||
niko_classname,
|
||||
L"Niko",
|
||||
WS_POPUP,
|
||||
x, y,
|
||||
24 * 2, 32 * 2,
|
||||
NULL, NULL, module, NULL))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SetLayeredWindowAttributes(niko, RGB(0, 255, 0), 0, LWA_COLORKEY);
|
||||
|
||||
ShowWindow(niko, SW_SHOWNOACTIVATE);
|
||||
UpdateWindow(niko);
|
||||
|
||||
// Thread
|
||||
int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
|
||||
// Get starting position
|
||||
RECT area;
|
||||
GetWindowRect(niko, &area);
|
||||
|
||||
// Just keep walking down
|
||||
for (;;) {
|
||||
// Dispatch messages
|
||||
unsigned long tick = GetTickCount();
|
||||
for (;;) {
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, niko, 0, 0, PM_REMOVE) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
if (GetTickCount() - tick >= 1000 / 60)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
niko_offset += 2;
|
||||
if (area.top + niko_offset >= screenHeight)
|
||||
break;
|
||||
SetWindowPos(niko, NULL, area.left, area.top + niko_offset, 0, 0, SWP_NOSIZE);
|
||||
InvalidateRect(niko, NULL, FALSE);
|
||||
}
|
||||
|
||||
DestroyWindow(niko);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (niko_bmps[i])
|
||||
DeleteObject(niko_bmps[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include <windows.h>
|
||||
|
||||
static const WCHAR niko_classname[] = L"niko";
|
||||
static HWND niko = NULL;
|
||||
static HBITMAP niko_bmps[3] = {NULL};
|
||||
static int niko_offset = 0;
|
||||
|
||||
// Window procedure
|
||||
LRESULT CALLBACK niko_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_CLOSE:
|
||||
return 0;
|
||||
|
||||
case WM_PAINT: {
|
||||
static int frame = 0;
|
||||
if (niko_offset % 32 >= 16) {
|
||||
frame = 1;
|
||||
} else {
|
||||
if ((niko_offset / 32) % 2)
|
||||
frame = 0;
|
||||
else
|
||||
frame = 2;
|
||||
}
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
BITMAP bitmap;
|
||||
HDC hdcMem;
|
||||
HGDIOBJ oldBitmap;
|
||||
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
hdcMem = CreateCompatibleDC(hdc);
|
||||
oldBitmap = SelectObject(hdcMem, niko_bmps[frame]);
|
||||
|
||||
GetObject(niko_bmps[frame], sizeof(bitmap), &bitmap);
|
||||
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
|
||||
|
||||
SelectObject(hdcMem, oldBitmap);
|
||||
DeleteDC(hdcMem);
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_niko(int x, int y)
|
||||
{
|
||||
// Create
|
||||
HINSTANCE module = GetModuleHandleW(NULL);
|
||||
niko_bmps[0] = LoadBitmapW(module, L"NIKO1");
|
||||
niko_bmps[1] = LoadBitmapW(module, L"NIKO2");
|
||||
niko_bmps[2] = LoadBitmapW(module, L"NIKO3");
|
||||
|
||||
WNDCLASSEXW wc;
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = niko_proc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = module;
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = niko_classname;
|
||||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
if (!RegisterClassEx(&wc))
|
||||
return 1;
|
||||
|
||||
if (!(niko = CreateWindowExW(WS_EX_COMPOSITED | WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
|
||||
niko_classname,
|
||||
L"Niko",
|
||||
WS_POPUP,
|
||||
x, y,
|
||||
24 * 2, 32 * 2,
|
||||
NULL, NULL, module, NULL))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SetLayeredWindowAttributes(niko, RGB(0, 255, 0), 0, LWA_COLORKEY);
|
||||
|
||||
ShowWindow(niko, SW_SHOWNOACTIVATE);
|
||||
UpdateWindow(niko);
|
||||
|
||||
// Thread
|
||||
int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
|
||||
// Get starting position
|
||||
RECT area;
|
||||
GetWindowRect(niko, &area);
|
||||
|
||||
// Just keep walking down
|
||||
for (;;) {
|
||||
// Dispatch messages
|
||||
unsigned long tick = GetTickCount();
|
||||
for (;;) {
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, niko, 0, 0, PM_REMOVE) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
if (GetTickCount() - tick >= 1000 / 60)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
niko_offset += 2;
|
||||
if (area.top + niko_offset >= screenHeight)
|
||||
break;
|
||||
SetWindowPos(niko, NULL, area.left, area.top + niko_offset, 0, 0, SWP_NOSIZE);
|
||||
InvalidateRect(niko, NULL, FALSE);
|
||||
}
|
||||
|
||||
DestroyWindow(niko);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (niko_bmps[i])
|
||||
DeleteObject(niko_bmps[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue