1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Python] Identify the montiors and show some text or image in windows

Discussão em 'Python' iniciado por Stack, Outubro 1, 2024 às 11:53.

  1. Stack

    Stack Membro Participativo

    I am working on a project where I have to detect all the monitors connected to the system and show some text or image on the specific monitor of the choice. Even the monitor/display is in duplicate screen mode.

    So, first I tried to go through the winapi and cpanel lib in Python and prepare the following code to detect the display in both duplicate and extended screen mode.

    I am using a Windows 11 OS.

    import ctypes

    class RECT(ctypes.Structure):
    _fields_ = [
    ('left', ctypes.c_ulong),
    ('top', ctypes.c_ulong),
    ('right', ctypes.c_ulong),
    ('bottom', ctypes.c_ulong)
    ]

    def dump(self):
    return map(int, (self.left, self.top, self.right, self.bottom))

    # Define POINTL structure
    class POINTL(ctypes.Structure):
    _fields_ = [
    ("x", ctypes.c_long),
    ("y", ctypes.c_long),
    ]


    # Enumerate monitors
    def enumerate_monitors():
    user32 = ctypes.windll.user32

    # Get number of display settings
    num_settings = 0
    while True:
    dev_mode = DEVMODEW()
    dev_mode.dmSize = ctypes.sizeof(dev_mode)
    if not user32.EnumDisplaySettingsW(ctypes.c_void_p(), num_settings, ctypes.byref(dev_mode)):
    break
    num_settings += 1

    # Get monitor handle
    h_monitor = user32.MonitorFromHandle(ctypes.c_void_p())

    # Get monitor rectangle
    rect = ctypes.POINTER(RECT)
    user32.GetMonitorInfoA(h_monitor, ctypes.byref(rect))

    yield h_monitor, rect


    # Define DEVMODEW structure
    class DEVMODEW(ctypes.Structure):
    _fields_ = [
    ("dmDeviceName", ctypes.c_wchar * 32),
    ("dmSpecVersion", ctypes.c_ushort),
    ("dmDriverVersion", ctypes.c_ushort),
    ("dmSize", ctypes.c_ushort),
    ("dmDriverExtra", ctypes.c_ushort),
    ("dmFields", ctypes.c_dword),
    ("dmPosition", POINTL),
    ("dmDisplayOrientation", ctypes.c_int),
    ("dmDisplayFixedOutput", ctypes.c_int),
    ("dmColor", ctypes.c_int),
    ("dmDuplex", ctypes.c_int),
    ("dmYResolution", ctypes.c_int),
    ("dmTTOption", ctypes.c_int),
    ("dmCollate", ctypes.c_int),
    ("dmFormName", ctypes.c_wchar * 32),
    ("dmLogPixels", ctypes.c_int),
    ("dmBitsPerPel", ctypes.c_int),
    ("dmPelsWidth", ctypes.c_int),
    ("dmPelsHeight", ctypes.c_int),
    ("dmDisplayFlags", ctypes.c_int),
    ("dmNup", ctypes.c_int),
    ("dmDisplayFrequency", ctypes.c_int),
    ("dmICMMethod", ctypes.c_int),
    ("dmICMIntent", ctypes.c_int),
    ("dmMediaType", ctypes.c_int),
    ("dmDitherType", ctypes.c_int),
    ("dmReserved1", ctypes.c_int),
    ("dmReserved2", ctypes.c_int),
    ("dmPannableWidth", ctypes.c_int),
    ("dmPannableHeight", ctypes.c_int),
    ("dmReserved3", ctypes.c_int),
    ("dmReserved4", ctypes.c_int),
    ]

    # Display text on a specific monitor
    def display_text_on_monitor(h_monitor, text):
    user32 = ctypes.windll.user32

    # Create a window on the specified monitor
    hwnd = user32.CreateWindowExW(
    0,
    "STATIC",
    text,
    0,
    0,
    0,
    0,
    0,
    h_monitor,
    ctypes.c_void_p(),
    ctypes.c_void_p(),
    ctypes.c_void_p(),
    )

    # Show window
    user32.ShowWindow(hwnd, 5)


    # Handle duplicate monitors
    def handle_duplicate_monitors():
    i = 1
    for h_monitor, rect in enumerate_monitors():
    print(f"Monitor {i}:")
    print(f" Handle: {h_monitor}")
    print(f" Rectangle: {rect}")
    display_text_on_monitor(h_monitor, f"Hello, Monitor {i}!")
    i += 1


    # Usage
    handle_duplicate_monitors()


    I can able to detact the monitor with winapi or cpanel but it will only detact one monitor if the multimonior setup is on duplicate display mode.

    So, I tried different method but there is no luck.

    Continue reading...

Compartilhe esta Página