More improvements to window creation

This commit is contained in:
dlannan 2025-10-15 22:41:41 +10:30
parent 1f0030383a
commit b618b0c4f7
3 changed files with 131 additions and 25 deletions

View File

@ -1,4 +1,4 @@
internal error: Template 'partials/statistics_js.html' not found in runtime:0
internal error: Template 'partials/config_modules_js.html' not found in runtime:0
Lua stack traceback:
editor\twig/aspect\error.lua:103: in function 'new'
editor\twig/aspect\template.lua:395: in function 'render'

View File

@ -1,6 +1,8 @@
------------------------------------------------------------------------------------------------------------
local ffi = require( "ffi" )
local tinsert = table.insert
local kernel32 = ffi.load( "kernel32.dll" )
local user32 = ffi.load( "user32.dll" )
local comdlg32 = ffi.load( "Comdlg32.dll" )
@ -19,25 +21,124 @@ local Colors = {
}
ffi.cdef[[
void Sleep(uint32_t ms);
typedef unsigned long DWORD;
typedef int BOOL;
typedef const char* LPCSTR;
typedef unsigned int HANDLE;
typedef unsigned int HWND;
typedef unsigned long *ULONG_PTR;
typedef long LPARAM;
typedef int (*WNDENUMPROC)(HWND hwnd, LPARAM lParam);
typedef struct enumData {
uint64_t lparam[1];
const char * title;
} enumData;
} enumData;
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
long pcPriClassBase;
DWORD dwFlags;
char szExeFile[260];
} PROCESSENTRY32;
typedef struct { long left; long top; long right; long bottom; } RECT;
HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
BOOL Process32First(HANDLE hSnapshot, PROCESSENTRY32 *lppe);
BOOL Process32Next(HANDLE hSnapshot, PROCESSENTRY32 *lppe);
BOOL CloseHandle(HANDLE hObject);
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
DWORD GetWindowThreadProcessId(HWND hWnd, DWORD *lpdwProcessId);
BOOL IsWindowVisible(HWND hWnd);
DWORD WaitForInputIdle(HANDLE hProcess, DWORD dwMilliseconds);
HWND GetForegroundWindow(void);
int GetSystemMetrics(int nIndex);
int AdjustWindowRect(RECT* lpRect, unsigned long dwStyle, int bMenu);
long GetWindowLongA(unsigned int hWnd, int nIndex);
int SystemParametersInfoW(unsigned int uiAction, unsigned int uiParam, RECT* pvParam, unsigned int fWinIni);
BOOL SystemParametersInfoW(unsigned int uiAction, unsigned int uiParam, RECT* pvParam, unsigned int fWinIni);
int SetWindowPos(unsigned int hWnd, void* hWndInsertAfter, int X, int Y, int cx, int cy, unsigned int uFlags);
BOOL SetWindowPos(unsigned int hWnd, void* hWndInsertAfter, int X, int Y, int cx, int cy, unsigned int uFlags);
void Sleep(uint32_t ms);
]]
require("ffi.windows")
-- -----------------------------------------------------------------------------------
local TH32CS_SNAPPROCESS = 0x00000002
local process_parents = {}
local process_childs = {}
local function GetAllProcesses( )
-- Setup Toolhelp snapshot
local snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
if snapshot == -1 then return end
local entry = ffi.new("PROCESSENTRY32[1]")
entry[0].dwSize = ffi.sizeof("PROCESSENTRY32")
local found = false
local first_entry = kernel32.Process32First(snapshot, entry)
if first_entry ~= 0 then
repeat
process_parents[entry[0].th32ParentProcessID] = process_parents[entry[0].th32ParentProcessID] or {}
tinsert(process_parents[entry[0].th32ParentProcessID], entry[0].th32ProcessID)
process_childs[entry[0].th32ProcessID] = entry[0].th32ParentProcessID
print(entry[0].th32ProcessID, entry[0].th32ParentProcessID)
until kernel32.Process32Next(snapshot, entry) == 0
end
kernel32.CloseHandle(snapshot)
end
-- -----------------------------------------------------------------------------------
function CheckChildren( win_pid, target_pid )
if( process_parents[target_pid] ) then
for i, v in ipairs(process_parents[target_pid]) do
print(v, win_pid, target_pid)
if v == win_pid then return true end
end
end
return false
end
-- -----------------------------------------------------------------------------------
local function FindWindowByProcId( proc_handle, proc_id, timeout_ms )
timeout_ms = timeout_ms or 5000
-- Wait until process is idle (i.e., its message queue is waiting)
local wait_result = ffi.C.Sleep(timeout_ms)
-- Get the currently active (foreground) window
local hwnd = user32.GetForegroundWindow()
if hwnd == nil then
print("No foreground window found.")
return nil
end
-- Check if it belongs to our target process
local pid_ptr = ffi.new("DWORD[1]")
user32.GetWindowThreadProcessId(hwnd, pid_ptr)
return hwnd
end
-- -----------------------------------------------------------------------------------
local function AssocQ( outstr, bsize )
local ftype = ffi.cast("char *", ffi.string("http"))
local verb = ffi.cast("char *", ffi.string("open"))
@ -285,18 +386,23 @@ end
------------------------------------------------------------------------------------------------------------
return {
CreateWindow = CreateWindow,
SetWindowPos = SetWindowPos,
SetTransparentBlend = SetTransparentBlend,
GetHwndFromProcess = GetHwndFromProcess,
RemoveWindowBorders = RemoveWindowBorders,
WindowsFileSelect = WindowsFileSelect,
WindowsFolderSelect = WindowsFolderSelect,
execute = execute,
shellexecute = shellexecute,
Sleep = ffi.C.Sleep,
GetFile = GetFile,
getDefaultBrowser = getDefaultBrowser,
CreateWindow = CreateWindow,
SetWindowPos = SetWindowPos,
SetTransparentBlend = SetTransparentBlend,
GetHwndFromProcess = GetHwndFromProcess,
RemoveWindowBorders = RemoveWindowBorders,
WindowsFileSelect = WindowsFileSelect,
WindowsFolderSelect = WindowsFolderSelect,
execute = execute,
shellexecute = shellexecute,
Sleep = ffi.C.Sleep,
GetFile = GetFile,
FindWindowByProcId = FindWindowByProcId,
GetAllProcesses = GetAllProcesses,
getDefaultBrowser = getDefaultBrowser,
kernel = kernel32,
user = user32,

View File

@ -38,12 +38,12 @@ print("BROWSER SETUP")
local browser, bsize = winu.getDefaultBrowser()
local browser_path = ffi.string(browser)..[[ -new-window "http://localhost:9190/index.html"]]
hproc_browser, hthread_browser, si_browser = execute(browser_path)
sleep(200)
hproc_browser, hthread_browser, pi_browser = execute(browser_path)
-- Need to make this more generic (ie browser agnostic)
local browserhwnd = GetHwndFromProcess( hthread_browser, "Mozilla Firefox" )
-- local browserhwnd = winu.GetHwndFromProcess( hthread_browser, "Mozilla Firefox" )
local browserhwnd = winu.FindWindowByProcId(pi_browser[0].hProcess, hproc_browser, 400)
-- local browserhwnd = user32.FindWindowA( nil, "http://localhost:9190/index.html")
print(hproc_browser, hthread_browser, si_browser)
-- print(hproc_browser, hthread_browser, si_browser)
if(browserhwnd) then
sleep(100) -- Let things setup (window pos etc)
local style = user32.GetWindowLongA(browserhwnd, -16)
@ -63,10 +63,10 @@ print("SOKOL-LUAJIT SETUP")
local width = rect[0].right - rect[0].left
local height = rect[0].bottom - rect[0].top
local sokolluajit_path = [["bin/win64/luajit.exe" "editor/editor.lua" ]]..string.format(" %d %d", width, height)
hproc_sokol, hthread_sokol, si_sokol = execute(sokolluajit_path)
sleep(200)
hproc_sokol, hthread_sokol, pi_sokol = execute(sokolluajit_path)
print(hproc_sokol, hthread_sokol, si_sokol)
local sokolhwnd = GetHwndFromProcess( hthread_sokol, "editor - sokol" )
-- local sokolhwnd = GetHwndFromProcess( hthread_sokol, "editor - sokol" )
local sokolhwnd = winu.FindWindowByProcId(pi_sokol[0].hProcess, hproc_sokol, 200)
-- local sokolhwnd = user32.FindWindowA( nil, "editor - sokol")
if(sokolhwnd) then
sleep(100) -- Let things setup (window pos etc)