--lua
local ffi = require 'ffi'
local C = ffi.C
ffi.cdef [[
typedef struct lua_State lua_State;
lua_State *luaL_newstate();
void Sleep(unsigned int dwMilliseconds);
void luaL_openlibs(lua_State *L);
int luaL_loadstring (lua_State *L, const char *s);
void lua_call (lua_State *L, int nargs, int nresults);
]]
local lua_code = [=====[
local mega_f = function(...)
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
typedef void* HANDLE;
typedef void* HWND;
typedef void* HINSTANCE;
typedef unsigned int UINT;
typedef int BOOL;
typedef const char* LPCSTR;
typedef long LONG;
typedef unsigned int DWORD;
typedef unsigned long long UINT_PTR;
typedef void* LPVOID;
typedef void* HMODULE;
typedef int (__stdcall *THREAD_START_ROUTINE)(LPVOID lpThreadParameter);
typedef UINT_PTR (__stdcall *TIMERPROC)(HWND, UINT, UINT_PTR, DWORD);
typedef unsigned int WPARAM;
typedef long LPARAM;
typedef void* HFONT;
HWND __stdcall CreateWindowExA(
LONG dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
LONG dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
void* hMenu,
HINSTANCE hInstance,
void* lpParam
);
BOOL __stdcall ShowWindow(
HWND hWnd,
int nCmdShow
);
BOOL __stdcall UpdateWindow(
HWND hWnd
);
int __stdcall MessageBoxTimeoutA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType,
UINT wLanguageId,
UINT dwMilliseconds
);
BOOL __stdcall DestroyWindow(
HWND hWnd
);
DWORD __stdcall GetCurrentThreadId();
HMODULE __stdcall GetModuleHandleA(
LPCSTR lpModuleName
);
HANDLE __stdcall CreateThread(
void* lpThreadAttributes,
size_t dwStackSize,
THREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
DWORD* lpThreadId
);
BOOL __stdcall CloseHandle(
HANDLE hObject
);
UINT_PTR __stdcall SetTimer(
HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
);
BOOL __stdcall KillTimer(
HWND hWnd,
UINT_PTR uIDEvent
);
typedef struct {
int x;
int y;
} POINT;
typedef struct {
HWND hwnd;
UINT message;
uintptr_t wParam;
intptr_t lParam;
DWORD time;
POINT pt;
} MSG;
typedef intptr_t LRESULT;
typedef struct {
uint32_t size;
uint32_t pos_x;
uint32_t pos_y;
uint32_t width;
uint32_t height;
uint32_t timeout;
const char* text;
} HintStruct;
BOOL __stdcall GetMessageA(
MSG* lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
);
BOOL __stdcall TranslateMessage(
const MSG* lpMsg
);
LRESULT __stdcall DispatchMessageA(
const MSG* lpMsg
);
int __stdcall SendMessageA(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
HFONT __stdcall CreateFontA(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
unsigned long fdwItalic,
unsigned long fdwUnderline,
unsigned long fdwStrikeOut,
unsigned long fdwCharSet,
unsigned long fdwOutputPrecision,
unsigned long fdwClipPrecision,
unsigned long fdwQuality,
unsigned long fdwPitchAndFamily,
LPCSTR lpszFace
);
void Sleep(unsigned int dwMilliseconds);
static const int WM_SETFONT = 0x0030;
typedef struct lua_State lua_State;
lua_State *luaL_newstate();
void Sleep(unsigned int dwMilliseconds);
void luaL_openlibs(lua_State *L);
void lua_call (lua_State *L, int nargs, int nresults);
typedef int (*lua_CFunction)(lua_State *L);
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
]]
local user32 = ffi.load("user32")
local kernel32 = ffi.load("kernel32")
local Gdi32 = ffi.load("Gdi32.dll")
local sleep = C.Sleep
-- Переменная для хранения дескриптора окна с сообщением
local previousMessageWindow = nil
local function createWindow(HintStruct)
local hwnd = user32.CreateWindowExA(
0x08000000 + 0x8, -- dwExStyle WS_EX_NOACTIVATE | WS_EX_TOPMOST
"STATIC" , -- lpClassName
HintStruct.text, -- lpWindowName
0x80000000, -- dwStyle WS_POPUP
HintStruct.pos_x, -- x
HintStruct.pos_y, -- y
HintStruct.width, -- nWidth
HintStruct.height,-- nHeight
nil, -- hWndParent
nil, -- hMenu
nil, -- hInstance
nil -- lpParam
)
-- Создаем шрифт
local hFont = Gdi32.CreateFontA(
HintStruct.size, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"
)
-- Устанавливаем шрифт
local res = user32.SendMessageA(hwnd, C.WM_SETFONT, ffi.cast("WPARAM", hFont), 1)
user32.ShowWindow(hwnd, 5) -- SW_SHOW
user32.UpdateWindow(hwnd)
return hwnd
end
local function createTimer(hwnd, timeout)
local timerId = user32.SetTimer(hwnd, 1, timeout, nil)
return timerId
end
local function destroyTimer(hwnd, timerId)
user32.KillTimer(hwnd, timerId)
end
local function createWindowAsync(HintStruct)
HintStruct = ffi.cast("HintStruct*", HintStruct)
-- Если предыдущее окно существует, закрываем его
if previousMessageWindow ~= nil then
print"_____"
user32.DestroyWindow(previousMessageWindow)
print"XXXX"
previousMessageWindow = nil
end
local hwnd = createWindow(HintStruct)
-- Сохраняем дескриптор текущего окна как предыдущий
previousMessageWindow = hwnd
if hwnd ~= nil then
local timerId = createTimer(hwnd, HintStruct.timeout) -- Set timer for specified timeout
-- Н<вырезано анти-матом>кирующее ожидание событий окна
local start = os.clock()
while os.clock() - start < HintStruct.timeout / 1000 do
local msg = ffi.new("MSG")
local result = user32.GetMessageA(msg, nil, 0, 0)
if type(result) == 'number' and result > 0 then
user32.TranslateMessage(msg)
user32.DispatchMessageA(msg)
end
end
destroyTimer(hwnd, timerId) -- Destroy timer
user32.DestroyWindow(hwnd) -- Destroy window
-- Обнуляем дескриптор предыдущего окна, так как оно уже было закрыто
previousMessageWindow = nil
else
print("Failed to create window")
end
return 0
end
local function hint(text, size, pos_x, pos_y, width, height, timeout)
print(text)
print(size)
print(pos_x)
local HintStruct = ffi.new("HintStruct")
HintStruct.text = text
HintStruct.size = size
HintStruct.pos_x = pos_x
HintStruct.pos_y = pos_y
HintStruct.width = width
HintStruct.height = height
HintStruct.timeout = timeout
local threadId = ffi.new("DWORD[1]")
local threadHandle = kernel32.CreateThread(nil, 0, ffi.cast("THREAD_START_ROUTINE", createWindowAsync), ffi.cast("LPVOID", HintStruct), 0, threadId)
kernel32.CloseHandle(threadHandle)
return 0
end
]=====]
local create_state = function(text, size, pos_x, pos_y, width, height, timeout)
local text = text and tostring(text) or "text"
local size = size or 24
local pos_x = pos_x or 0
local pos_y = pos_y or 0
local width = width or 400
local height = height or 200
local timeout = timeout or 5000
print(text)
print([[hint(']]..
text.."', "..size..", "..
pos_x..", "..pos_y..", "..
width..", "..height..", "..
timeout)
-- Создаем новый объект состояния Lua
local state = C.luaL_newstate()
-- Загружаем стандартные либы io, math, string и т.д.
C.luaL_openlibs(state)
-- Загружаем код Lua
C.luaL_loadstring(state, lua_code..[[hint(']]..
text.."', "..size..", "..
pos_x..", "..pos_y..", "..
width..", "..height..", "..
timeout..[[)
return 0
end
mega_f()]])
C.lua_call(state, 0, 0)
return 0
end
return create_state