Установка:
Написал модуль для возможности писать на PoSh прямо из пилота.
Можно писать одновременно как на lua, так и на PoSh внутри одного скрипта.
PoSh очень гибкий и компактный язык. Все его возможности доступны без необходимости установки дополнительных модулей (за исключением, кончено, специфических потребностей).
Примеры компактности языка:
№1
задача
Вот еще задачка. нужно найти все комментарии однострочные и многострочные, но данная регулярка не совсем корректно находит многострочные комментарии. Всего комментариев 7(для наглядности в тексте примера их пронумеровал и отметил жиром) из них: 5 однострочных и 2 многострочных
Вот рег: <!--(.+|(.|\s)*)-->
Вот пример текста:
<!--1 однострочный коментарий-->
текст <!-- 2 Это -- комментарий -->
текст
<!-- 3 многострочный
коментарий
текст какой-то--> текст
Эт0
к0д
какой-то
<!-- 4
это еще один
ногострочный
коментарий
--> текст
<!-- 5 это считается коментарием <!-- и это коментарием --> а этот текст уже нет-->
<!-- 6 --><!--7-->Решение на Pilot (только для Ansi, так как с utf pilot не работает вовсе)Кодlog clear_current
log mode compact
load_array %a C:\1.txt
for #i 1 size(%a)
set $a %a[#i]
while regexp(#p $r $a <!--.*?(-->|$))
log $r
while copy($r eval(size($r)-2) 3) != -->
set #i #i + 1
set $a %a[#i]
if regexp(#p $r $a ^.*?-->)
log $r
break
end_if
log %a[#i]
end_while
set $a string_replace($a $r "")
end_while
end_for
log save_current C:\2.txt
end_scriptРешение на luaКод--lua
log "clear" log "mode compact"
package.path = "LuaPlugins\\winapi\\?.lua;" .. package.path
package.path = "LuaPlugins\\?.lua;" .. package.path
setfenv(1, require'winapi')
require'utf8'
local s = readfile([[C:\1.txt]])
local f2 = io.open([[C:\2.txt]], "wb")
if s and f2 then
for w in s:gmatch("<%!%-%-.-%-%->") do
log (w .. "\r\n")
f2:write(w .. "\r\n")
end
f2:close()
end
exec ("notepad.exe", [[C:\2.txt]])
end_script ()
Решение на LuaPoSh. Сам код на ps занимает всего одну строку.
Исходная кодировка текста может быть как юникод, так и Ansi.--lua
require "LuaPoSh";PScode('void',{[[#}
#
[regex]::Matches((Get-Content C:\1.txt), '<!--.+?-->').value > C:\2.txt;C:\2.txt
#
]]})
задача
Hello everyone. I have a problem with showwindow() state commands.
In the wiki page are given only these states:КодHIDE: спрятать окно
MAXIMIZE: развернуть во весь экран
MINIMIZE: свернуть
RESTORE: развернуть
SHOW: показать
TOP: вытащить на поверхность.
My question is: Are there any other states which I can use, because none of these worked for my problem?
I am trying to minimize and restore given window in windows 10 virtual desktops, without switching between the desktops automatically. I need more like a popup state. When I use RESTORE or MAXIMIZE state, it switches to the virtual desktop where the window is located automatically.Решение на luaКод--lua
package.path = "LuaPlugins\\winapi\\?.lua;" .. package.path
package.path = "LuaPlugins\\glue\\?.lua;" .. package.path
setfenv(1, require'winapi')
require[[winapi.winuser]]
local ffi = require("ffi")
ffi.cdef[[
BOOL ShowWindow(int hWnd, int nCmdShow);
]]
local SW_SHOWNOACTIVATE = 4
hndl=findwindow ("Калькулятор")
C.ShowWindow(hndl[1][1], SW_SHOWNOACTIVATE)
Решение на LuaPoSh. Сам код на ps занимает всего одну строку.--lua
require "LuaPoSh";PScode('void',{[[#}
#
WinApi ShowWindow([int]$input, 4)
#
]]}, findwindow("Калькулятор")[1][1])
задача
в папке D\3 находятся папки с фото,нужно оставить только файлы jpg которые больше 100х100 пиксРешение на luaКод--lua
local ffi = require('ffi')
local gdip = ffi.load('Gdiplus.dll')
local CP_ACP = 0
ffi.cdef[[
typedef unsigned int UINT;
typedef unsigned long DWORD;
typedef struct {UINT GdiplusVersion; int DebugEventCallback; bool SuppressBackgroundThread; bool SuppressExternalCodecs;} GdiplusStartupInput, *pGdiplusStartupInput;
bool DeleteFileA(const char *lpFileName);
int GdiplusStartup(int *token, pGdiplusStartupInput GdiplusStartupInput, int *output);
int GdiplusShutdown(int token);
int GdipDisposeImage(int image);
int GdipLoadImageFromFile(const wchar_t *filename, int *image);
int GdipGetImageWidth(int image, UINT *width);
int GdipGetImageHeight(int image, UINT *height);
int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
]]
function image_size(path)
local buf = ffi.new('wchar_t[?]', #path+1)
local StartupInput = ffi.new('GdiplusStartupInput', {1, 0, 0, 0})
local token, image, w, h = ffi.new('int[1]'), ffi.new('int[1]'), ffi.new('int[1]'), ffi.new('int[1]')
ffi.C.MultiByteToWideChar(CP_ACP, 0, path, #path, buf, ffi.sizeof(buf))
gdip.GdiplusStartup(token, StartupInput, nil)
gdip.GdipLoadImageFromFile(buf, image)
gdip.GdipGetImageWidth(image[0], w)
gdip.GdipGetImageHeight(image[0], h)
gdip.GdipDisposeImage(image[0])
gdip.GdiplusShutdown(token[0])
return w[0], h[0]
end
log 'clear' log 'mode compact'
local path = [[D:\3]] -- путь к папке
local resultarray, count = dir (path, "*.bmp;*.jpg") -- получить список всех файлов в формате bmp и jpg
log ("Найдено файлов: " .. count)
if count then -- если файлы найдены
for i=1, #resultarray do
local width, height = image_size( resultarray[i][1] )
log(resultarray[i][1].. '\tШирина: ' .. tostring(width) .. '\t'.. 'Высота: ' .. tostring(height)) -- размеры картинки
if width < 100 and height < 100 then -- если ширина и высота меньше 100
ffi.C.DeleteFileA( resultarray[i][1] ) -- удалить файл
end
end
end
local resultarray, count = dir (path, "*.?*") -- получить список всех файлов
log ("Найдено файлов: " .. tostring(count))
if count then -- если файлы найдены
for i=1, #resultarray do
if resultarray[i][4] ~= '.jpg' then -- если не jpg
log('Удаление файла: ' .. resultarray[i][1])
ffi.C.DeleteFileA( resultarray[i][1] ) -- удалить файл
end
end
end
Решение на LuaPoSh. Сам код на ps в 5 раза короче и проще, чем на lua.--lua
require "LuaPoSh";PScode('void',{[[#}
#
$path = 'D:\3'
function Check-PicSize($p){#}
$img = [Drawing.Image]::FromFile( $p.fullname )
if($img.width -gt 100 -and $img.Height -gt 100)
{$img.Dispose(); $true}else{$img.Dispose(); $false}
}
Get-ChildItem $path -file -rec|ForEach{#}
if(!($_.Extension -eq '.jpg' -and (Check-PicSize $_)))
{ri $_.FullName}
}
#
]]})
Синтаксис:
PScode('return/void',{[[#}
#pscode;
#pscode
]]},<arg1>,<arg2>,<arg3>)
Прыыыкона.
Ток пытался погуглить чо за Lua Posh список команд посматреть да примеры какие но толком ничего не нашол
--lua
package.path = "LuaPlugins\\winapi\\?.lua;" .. package.path
package.path = "LuaPlugins\\?.lua;" .. package.path
setfenv(1, require'winapi')
require'utf8'
local f1, f2, f3 = {}, {}, {}
for s in string.gmatch(readfile([[C:\1.txt]]), "[^\r\n]+") do
table.insert(f1, s)end
for s in string.gmatch(readfile([[C:\2.txt]]), "[^\r\n]+") do
table.insert(f2, s)end
for s in string.gmatch(readfile([[C:\3.txt]]), "[^\r\n]+") do
table.insert(f3, s)end
local f4 = io.open([[C:\4.txt]], "wb")
if f1 and f2 and f3 and f4 then
-- чтение файлов в массивы
local arr1, arr2, arr3 = {}, {}, {}
for i=1,#f1 do arr1[#arr1+1] = f1[i]:match("%d+%s+(.+)") end
for i=1,#f2 do arr2[#arr2+1] = string.gsub(f2[i]:match("%d+%s+(.+)"), " ", ":") end
for i=1,#f3 do arr3[#arr3+1] = f3[i]:match("%d+%s+(.+)") end
local min = math.min (#arr1, #arr2, #arr3)
for i = 1, min do -- запись в файл
f4:write(arr1[i])
f4:write(":nnnnnn|")
f4:write(arr2[i])
f4:write("|")
f4:write(arr3[i])
f4:write("\r\n")
end
f4:close() -- закрыть файл
exec ("notepad.exe", [[C:\4.txt]])
else
log ("Какой-то из файлов не открылся или не найден")
end
Как он может решить задачу findcolor/findimage?
Совет:Имейте в виду, что путь для сохранения будет запрошен первым, хоть и находится в конце кода. Что бы избежать ошибок, не стоит использовать одинаковые подсказки для prompt( или смотрите следующий пример).[regex]::Matches(Get-Content (text_prompt "Путь:"), '<!--.+?-->').value >(text_prompt "Путь:")
Get-PrUocess : Имя "Get-PrUocess" не распознано как имя командлета, функции, файла сценария или выполняемой программы.
Проверьте правильность ...
Ладно. С многопоточкой твой LuaPosh точно не справится)
Добавлен вывод сообщений на экран. Msg_box "text"--lua
log "clear";require "luaposh"
PScode('return',{[[#}
#
Get-KeyState 0x01 # пропускаем клик при запуске скрипта
# Поток 1
Start-Timer @"
if ((Get-KeyState 0x01)){#} # отслеживаем нажатие левой кнопки мыши
msg_box "Нажата левая кнопка мыши" # действия таймера
log "ЛКМ" # действия таймера
}
"@ 500 # интервал выполнения 500 ms
Get-KeyState 0x20 # пропускаем пробел, нажатый до запуска
# Поток 2
Start-Timer @"
if ((Get-KeyState 0x20)){#} # отслеживаем нажатие пробела
msg_box "Нажат пробел" # действия таймера
log "ПРОБЕЛ" # действия таймера
}
"@ 500 # интервал выполнения 500 ms
# Основной поток
while((on)){#}
log ("Я просто считаю: "+$i++)
sleep -m 250
}
#
]]})
Демонстрация вывода данных в лог
Доброго времени суток!
Подскажите, как с его помощью получить из файла все слова, которые начинаются на "@"?
--lua
log"clear";log"mode compact"
require"luaposh";PScode('return',{[[#}
$path= "C:\1.txt"
log ([regex]::Matches((Get-Content $path), '@\S+').value)
]]})
Небольшие изменения и исправления.
Архив с обновлением в первом посте.
Дано:
89997001234:Forsik007:Алла Пугачева:uopilot@mail.ru:zdarovabanditi
Нужно с помощью регулярного выражения найти : 1234, Forsik007, uopilot@mail.ru и записать в переменные.
Благодаря команде split, мы можем обойтись без постройки сложных паттернов регэкспа.
Может именно rar не хочет открывать у вас.
[attachmentid=3303]
Prompt с возможностью выбора вариантов.
Скорость работы этой либы отличается от скорости запуска PowerShell? Прошу понять правильно, просто зачастую я быстрее руками что-то сделаю, чем ждать запуска этой наковальни
Долго первый запуск, потом нормально.
У меня старт занимает 1.73 сек. Поработаю еще над скоростью запуска.
Прочитать файл, выбрав его в окне:--lua
log "clear";log"mode compact";require "luaposh"
PScode('return',{[[#}
#
$filePath = ShowDialog-FilePath
log $filePath
$data = Get-Content $filePath -Encoding UTF8
log $data
#
]]})
Удалить папку, выбрав её в окне:--luaВторой параметр-подсказка необязательный.
log "clear";log"mode compact";require "luaposh"
PScode('return',{[[#}
#
$folderPath = ShowDialog-FolderPath 'Что будем удалять?'
log $folderPath
Remove-Item $folderPath
#
]]})
Обновляет имеющиеся файлы.
Загружает отсутствующие.
Пример:--luaПараметры $FtpLogin и $FtpPass не требуются, если сервер имеет открытый доступ.
log "clear";log"mode compact";require "luaposh"
PScode('return',{[[#}
#
$FtpPath = 'ftp://my.ftpurl.ru/docs/'
$LocalPath = 'C:\files\docs\'
$FtpLogin = 'john77'
$FtpPass = 'qwe123'
$Result = Sync-FtpFolder $ftpPath $localPath $FtpLogin $FtpPass
log $Result
#
]]})
Результат в логе:Код[1/3]scan.png
Files identical
[2/3]document.docx
FTP file newer
Downloaded
[3/3]test.txt
FTP file older
Uploaded
--luaВерхний статус-бар отображает: цвет|координаты|масштаб.
log "clear";log"mode compact";require "luaposh"
PScode('return',{[[#}
#
$color = Show-ScreenMagnifier
log $color
#
]]})
Нижний статус-бар показывает цвет, который был определен под курсором.
Использование:
num+ = увеличить масштаб
num- = уменьшить масштаб
num0 = сбросить масштаб
Когда курсор наведен на нужный цвет, нажмите Esc. Лупа закроется, выбранный цвет будет записан в переменную.
Демонстрация:
--lua
log "clear";log"mode compact";require "luaposh"
PScode('return',{[[#}
#
$result = Check-UrlVirus yandex.ru
log $result
#
]]})
Добавлены параметры для экранной лупы.
-freezScreen
Замораживает экран. Пригодится если цвет, который вы хотите определить, меняется при наведении курсора.
Выбранный цвет будет занесен в буфер обмена.
Задает формат определяемого цвета.
Поколдовал над запуском.
Установка:--luaПример задачи:
require"luaposh";log "clear";log "mode compact"
PScode('return',{[[#}
#
Install-Selenium
log
#
]]})
- Открыть яндекс
- Найти вики пилота
- Открыть вики
- Открыть страницу функции Exec
- Показать в логе описание функции
code--lua
require"luaposh";log "clear";log "mode compact"
PScode('return',{[[#}
#
Start-Selenium
$luaFunction = 'Exec (Lua)'
$Chrome = Start-SeChrome
$Chrome.Url = 'https://ya.ru'
sleep 1
$Chrome.FindElementByName('text').SendKeys('uopilot')
sleep 1
$Chrome.FindElementByClassName('search2__button').click()
sleep 2
$Chrome.FindElementByPartialLinkText('uokit').click()
sleep 1
[void]$Chrome.SwitchTo().Window($Chrome.WindowHandles[1])
$Chrome.FindElementById('searchInput').SendKeys($luaFunction)
sleep 1
$Chrome.FindElementByName('go').click()
$description = $chrome.FindElementsByTagName('p')[0].text
log $description
#
]]})демонстрацияСлипы добавлены просто для возможности понаблюдать за происходящим.
Результат в логе:Цитатаexec - запуск внешнего приложения. Не приостанавливает скрипт на время работы приложения. Для ожидания завершения используйте ExecAndWait (Lua). UoPilot запускать от администратора.
Для примера выше должен быть установлен Chrome browser.
Пишите, если что-то не будет работать. Буду исправлять.
Все его возможности пока не знаю, так что описывайте вашу задачу, постараюсь дать решение.
Тернарный оператор.
Синтаксис сделал обычный: boolean |?? если истина : если ложь
Если на часах 11 вечера, то пора идти спать:--lua
log"clear";log"mode compact";require"luaposh"
PScode('return',{[[#}
#
$time = (Get-Date).Hour -eq 23 |?? "Пора спать" : "Еще не ночь"
log $time
#
]]})
В зависимости от времени суток будет запущено приложение:--lua
log"clear";log"mode compact";require"luaposh"
PScode('void',{[[#}
#
(Get-Date).Hour -eq 23 |?? {Start "Calc"} : {Start "Notepad"}
#
]]})
Как работает хайд и есть ли возможность хайдить другие процессы?
--lua
log"clear";log"mode compact";require"luaposh"
PScode('void',{[[Hide-UoPilot]]})
Madeus, Hide-UoPilot прячет процесс пилота от защит, пытающихся его найти.
Насчет других процессов - да, можно. Но какие-то может быть и не получится, нужно будет тестить.
Сегодня или в ближайшие дни сделаю функцию для других процессов.
Набросал вот по-быстрому, попробуй.
--lua
log"clear";log"mode compact";require"luaposh"
PScode('void',{[[Start-HiddenProcess "C:\Notepad++\notepad++.exe"]]})
Скачал notepad++, у меня получилось.
А, ну этой команде нужно передавать два параметра. Второй можно любой на свой вкус.
Вот так попробуй:
В общем нужна помощь) Вчера скачал - распаковал - обновил - установил.
Попробовал
PScode('void',{[[Hide-UoPilot]]})
Переустанови luaposh. Удали luaposh.lua и папку posh, распакуй зоново архив, и обновись через апдейт.
Поправил сокрытие процесса, теперь по идее проблем быть не должно.
Еще немного доработал, теперь вот так выглядит:
И Start-HiddenProcess теперь можно запускать с одним параметром - путь к файлу.
Notepad не получится так запустить, так как его владелец не пользователь, а trustedinstaller.
Убирать имя уже запущенного процесса - на сколько я знаю, невозможно.
не нашел кнопки скачать)
Библиотека LuaPosh
Прикрепленные файлы
LuaPosh.rar ( 14,29 килобайт )
Кол-во скачиваний: 137
Вроде работало как-то давно у меня данная штуковина, а сейчас не робит и понять почему не могу, может подскажете в чем вообще может быть проблема?
--lua
require'LuaPoSh'
PScode('void',{[[luaposhhint]]})
HNDL = tbhndl()
local x = 0
-- выполнять данный блок 5 секунд
local time = os.clock() + 5
while os.clock() < time do
drawtext(HNDL, 'x = ' .. tostring(x) .. '\r\n' .. 'Текст', 200, 100, 36, 'Arial', 65280, 255)
x = x + 1
drawtext(HNDL, 'Текст\r\nМногострочный', 70, 300, 48, 'Segoe Print', 65279, 16000000)
drawtext(HNDL, 'Text 123 qwerty\r\nЕще текст\r\nи ещё' , 400, 150, 24, 'Comic Sans MS', 255, 0)
wait (10)
end
text_close() -- Закрыть luaPoshHint
Уважаемый фонарик... Как же вы уметете невзначай проходя мимо задать на первый взгляд простой и наивный вопрос и вынести этим весь мозг. Без вас было бы скучно.
подгружать через require
вызов:
local hint = require"hint"
hint(text, size, pos_x, pos_y, width, height, timeout)
--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(
0, -- dwExStyle
"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
--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
local hint = require"hint"
hint(text, size, pos_x, pos_y, width, height, timeout)
А можно как-нибудь посчитать в пикселях, сколько будет ширина текстовой переменной? Что-то типа, кол-во символов умножить на размер шрифта и на некоторый коэффициент. И тогда на строчке
local width = width or 400
можно. для этого есть спец функция в апи. тебе оно не надо. чуток просто подожди.
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)