- 1,469
- 433
- Версия MoonLoader
- .026-beta
Как можно проверить, что к компу подключена мышка, клава или то что включён монитор?
UPD1: Это как-то делается через ffi интерфейс и windows api. Решил начать с монитора и того что он вообще подключен.
Взял отсюда https://stackoverflow.com/a/14377835 код
и переделал на lua
Даже если я вытыкал DP кабель из ПК он всё равно определял наличие монитора, а все параметры не изменялись.
меня смущает почему тут указана видеокарта. Я же мониторы получаю. Если втыкать провод в другие слоты видюхи параметры тоже не меняются.
Я решил попробовать зайти по-другому и получать количество подключённых мониторов. Но значение также всегда было 1.
UPD2: ещё пытался определить что-то по хендлу монитора через хвид рабочего стола. Опять же значения с воткнутым провод и нет идентичны. Разрешение получается. У меня 2к. 1390 это за вычетом высоты панели задач. Следовательно я точно обращаюсь куда надо
UPD3: Я понял ошибку. Там выходит дивайс дивайса. Нужно функцией EnumDisplayDevicesA с 1 параметром nil получить адапторы дисплея и потом название адаптера засунуть в неё же уже получив мониторы этого адаптера. Ниже код определения подключённого хотя бы 1 монитора. Теперь нужно определить включён ли он. При выключении монитора никакие значения не меняются. StateFlags всегда 3
UPD1: Это как-то делается через ffi интерфейс и windows api. Решил начать с монитора и того что он вообще подключен.
Взял отсюда https://stackoverflow.com/a/14377835 код
C++:
BOOL IsDisplayConnected(int displayIndex = 0)
{
DISPLAY_DEVICE device;
device.cb = sizeof(DISPLAY_DEVICE);
return EnumDisplayDevices(NULL, displayIndex, &device, 0);
}
Lua:
local ffi = require 'ffi'
ffi.cdef [[
typedef struct {
uint32_t cb;
char DeviceName[32];
char DeviceString[128];
uint32_t StateFlags;
char DeviceID[128];
char DeviceKey[128];
} DISPLAY_DEVICE;
int EnumDisplayDevicesA(const char* lpDevice, int iDevNum, DISPLAY_DEVICE* lpDisplayDevice , unsigned long dwFlags);
]]
local user32 = ffi.load("user32")
local device = ffi.new("DISPLAY_DEVICE")
device.cb = ffi.sizeof("DISPLAY_DEVICE")
if user32.EnumDisplayDevicesA(nil, 0 --[[display index]], device, 0) ~= 0 and bit.band(device.StateFlags, 1 --[[DISPLAY_DEVICE_ACTIVE]]) ~= 0 then
print('+', ffi.string(device.DeviceName), ffi.string(device.DeviceString), ffi.string(device.DeviceID), ffi.string(device.DeviceKey))
else
print('-')
end
Код:
DeviceName - \\.\DISPLAY1
DeviceString - NVIDIA GeForce RTX 3060
StateFlags - 5
DeviceID - PCI\VEN_10DE&DEV_2487&SUBSYS_39771462&REV_A1
DeviceKey - \Registry\Machine\System\CurrentControlSet\Control\Video\{0FEAF640-675D-11ED-B368-B42E99F8170D}\0000
Я решил попробовать зайти по-другому и получать количество подключённых мониторов. Но значение также всегда было 1.
Lua:
local ffi = require 'ffi'
ffi.cdef [[
int GetSystemMetrics(int nIndex);
]]
local user32 = ffi.load("user32")
print(user32.GetSystemMetrics(80--[[SM_CMONITORS]]))
UPD2: ещё пытался определить что-то по хендлу монитора через хвид рабочего стола. Опять же значения с воткнутым провод и нет идентичны. Разрешение получается. У меня 2к. 1390 это за вычетом высоты панели задач. Следовательно я точно обращаюсь куда надо
Lua:
ffi = require 'ffi'
ffi.cdef [[
typedef void* HMONITOR;
typedef unsigned long DWORD;
typedef struct {
long left;
long top;
long right;
long bottom;
} RECT;
typedef struct {
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
} MONITORINFO;
void* GetDesktopWindow();
HMONITOR MonitorFromWindow(void* hwnd, unsigned long dwFlags);
int GetMonitorInfoA(HMONITOR hMonitor, MONITORINFO* lpmi);
]]
local user32 = ffi.load("user32")
local desktopWindow = user32.GetDesktopWindow()
local monitor = user32.MonitorFromWindow(desktopWindow, 2 --[[MONITOR_DEFAULTTONEAREST]])
if monitor ~= nil then
local monitorInfo = ffi.new("MONITORINFO")
monitorInfo.cbSize = ffi.sizeof("MONITORINFO")
if user32.GetMonitorInfoA(monitor, monitorInfo) ~= 0 and bit.band(monitorInfo.dwFlags, 1 --[[MONITORINFOF_PRIMARY]]) ~= 0 then
print(monitorInfo.cbSize, monitorInfo.dwFlags)
print(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right, monitorInfo.rcMonitor.bottom)
print(monitorInfo.rcWork.left, monitorInfo.rcWork.top, monitorInfo.rcWork.right, monitorInfo.rcWork.bottom)
else
print("-")
end
else
print("-")
end
Код:
[19:13:22.174496] (script) main.lua: 40 1
[19:13:22.174496] (script) main.lua: 0 0 2560 1440
[19:13:22.174496] (script) main.lua: 0 0 2560 1390
UPD3: Я понял ошибку. Там выходит дивайс дивайса. Нужно функцией EnumDisplayDevicesA с 1 параметром nil получить адапторы дисплея и потом название адаптера засунуть в неё же уже получив мониторы этого адаптера. Ниже код определения подключённого хотя бы 1 монитора. Теперь нужно определить включён ли он. При выключении монитора никакие значения не меняются. StateFlags всегда 3
Lua:
local ffi = require 'ffi'
ffi.cdef [[
typedef struct {
uint32_t cb;
char DeviceName[32];
char DeviceString[128];
uint32_t StateFlags;
char DeviceID[128];
char DeviceKey[128];
} DISPLAY_DEVICE;
int EnumDisplayDevicesA(const char* lpDevice, int iDevNum, DISPLAY_DEVICE* lpDisplayDevice , unsigned long dwFlags);
]]
local device = ffi.new("DISPLAY_DEVICE")
device.cb = ffi.sizeof("DISPLAY_DEVICE")
if ffi.C.EnumDisplayDevicesA(nil, 0 --[[device index]], device, 0) ~= 0 and bit.band(device.StateFlags, 1 --[[DISPLAY_DEVICE_ACTIVE]]) ~= 0 then
local display = ffi.new("DISPLAY_DEVICE")
display.cb = ffi.sizeof("DISPLAY_DEVICE")
if ffi.C.EnumDisplayDevicesA(device.DeviceName, 0 --[[device index]], display, 0) ~= 0 and bit.band(display.StateFlags, 1 --[[DISPLAY_DEVICE_ACTIVE]]) ~= 0 then
print('К пк подключён хотя бы 1 монитор')
else
print('Мониторы не найдены')
end
else
print('Не найден ни 1 адаптор дисплея')
end
Код:
DeviceName - \\.\DISPLAY1\Monitor0
DeviceString - Generic PnP Monitor
StateFlags - 3
DeviceID - MONITOR\ACR06D7\{4d36e96e-e325-11ce-bfc1-08002be10318}\0002
DeviceKey - \Registry\Machine\System\CurrentControlSet\Control\Class\{4d36e96e-e325-11ce-bfc1-08002be10318}\0002
Последнее редактирование: